[mythtv-users] HD-PVR issues (mythffmpeg and getcutlist) with MythArchive 0.26

Will Dormann wdormann at gmail.com
Sun Oct 21 22:59:05 UTC 2012


On 10/21/12 12:52 PM, Will Dormann wrote:
> 2) Despite setting MythArchive to use the cutlist, the output DVD
> doesn't use the cutlist.   Perhaps MythArchive hasn't caught up to my
> old 0.24 patch yet, or maybe I'm doing something wrong?

Ok, so looking deeper into mythburn.py I see that all of the cutlist
stuff is already in there.   I've manually re-added my patch to
re-encode before using mythtranscode to apply the cutlist, but now I'm
running into a new bug, which I believe is:

http://code.mythtv.org/trac/ticket/11090

When I try a lossless transcode (with cutlist), I get:

<snip>
2012-10-21 14:37:33.833495 E  Deadlock detected.  One buffer is full
when the other is empty!  Aborting
2012-10-21 14:37:33.835761 E  Transcoding
/var/lib/mytharchive/temp/work/1/2339_20121021154630.mpg failed


The suggested workarounds here
<http://www.mythtv.org/wiki/Mythtranscode#Fixing_.22Deadlock_detected._One_buffer_is_full_when_the_other_is_empty.21.22>
didn't help at all.  So it would seem, as ticket 11090 implies, that
lossless mythtranscode is just plain broken in 0.26.

So the alternative is to use projectx (in the MythArchive settings).
With a number of tweaks, I've gotten this to work.  Attached is the
patch that I've used.  It's really not well tested, and probably doesn't
even work on systems with non-HD-pvr capture devices.  I'd like to say
it's a work-in-progress, but since it works for me, I may not be
motivated to change it more.  :)   But the changes I made are:


1) Plenty of places in mythburn.py are references to a ".mv2" files.
I'm guessing that this is a typo that has propagated throughout the
script.  This is switched to ".m2v", which is what projectx creates.

2) I've replaced "mythffmpeg" with "ffmpeg".   I don't know why
mythffmpeg fails to work with the commandline that mythburn.py gives it,
so I've switched to just using ffmpeg for now.

3) Removed a stray reference to quoteFilename(), which doesn't even
exist anymore.

4) Removed the "-set ExternPanel.appendPidToFileName=1" command-line
flag to projectx, as it doesn't support a "-set" option anymore.  At
least with the ProjectX 0.90.4 that comes with mythbuntu.  I really
don't like the workaround, but because of removing that option, that
changes the audio channel (ac3 at least for me) file names.  Which requires:

5) In several places, change references from "stream0.ac3" to
"stream.ac3" to account for the change in 4) above.  I don't like this,
but I don't see an obvious way to get projectx to use the
appendPidToFileName option.


I've applied the mythtranscode-related changes from my mythburn.py 0.24
patch as well, but since mythtranscode seems to be currently broken, I'm
not sure if it works.

The other thing I needed to do with my system was to install the
"pmount" package, as that is used by mythburn.py, but it isn't provided
with mythbuntu.


With this patch, I've successfully burned a DVD of a short recording
that included a cutlist.


-WD
-------------- next part --------------
--- /usr/share/mythtv/mytharchive/scripts/mythburn.py.26	2012-10-21 12:02:30.507740358 -0400
+++ /usr/share/mythtv/mytharchive/scripts/mythburn.py	2012-10-21 18:10:08.462422263 -0400
@@ -764,7 +764,7 @@
     thumbList = ','.join(thumbList)
 
     if getthumbnails==True:
-        extractVideoFrames( os.path.join(getItemTempPath(itemnum),"stream.mv2"),
+        extractVideoFrames( os.path.join(getItemTempPath(itemnum),"stream.m2v"),
             os.path.join(getItemTempPath(itemnum),"chapter-%1.jpg"), thumbList)
 
     return chapters
@@ -1528,7 +1528,7 @@
 def encodeAudio(format, sourcefile, destinationfile, deletesourceafterencode):
     write( "Encoding audio to "+format)
     if format == "ac3":
-        cmd = "mythffmpeg -v 0 -y "
+        cmd = "ffmpeg -v 0 -y "
 
         if cpuCount > 1:
             cmd += "-threads %d " % cpuCount
@@ -1707,7 +1707,6 @@
         write("Using cutlist: %s" % cutlist_s)
 
     if (localfile != ""):
-        localfile = quoteFilename(localfile)
         if usecutlist == True:
             command = "mythtranscode --mpeg2 --honorcutlist %s --infile %s --outfile %s" % (cutlist_s, quoteCmdArg(localfile), quoteCmdArg(destination))
         else:
@@ -1777,7 +1776,8 @@
         write("Error: input file doesn't exist on local filesystem")
         return False
 
-    command = quoteCmdArg(path_projectx[0]) + " %s -id '%s' -set ExternPanel.appendPidToFileName=1 -out %s -name stream" % (quoteCmdArg(file), getStreamList(folder), quoteCmdArg(folder))
+#    command = quoteCmdArg(path_projectx[0]) + " %s -id '%s' -set ExternPanel.appendPidToFileName=1 -out %s -name stream" % (quoteCmdArg(file), getStreamList(folder), quoteCmdArg(folder))
+    command = quoteCmdArg(path_projectx[0]) + " %s -id '%s' -out %s -name stream" % (quoteCmdArg(file), getStreamList(folder), quoteCmdArg(folder))
     if usecutlist == True:
         command += " -cut %s" % quoteCmdArg(os.path.join(folder, "cutlist_x.txt"))
     write(command)
@@ -1815,7 +1815,7 @@
             PID = file[7:13]
             SubID = file[19:23]
             if PID == videoID_hex or SubID == videoID_hex:
-                os.rename(os.path.join(folder, file), os.path.join(folder, "stream.mv2"))
+                os.rename(os.path.join(folder, file), os.path.join(folder, "stream.m2v"))
             elif PID == audio1ID_hex or SubID == audio1ID_hex:
                 os.rename(os.path.join(folder, file), os.path.join(folder, "stream0." + file[-3:]))
             elif PID == audio2ID_hex or SubID == audio2ID_hex:
@@ -1832,11 +1832,11 @@
     files = os.listdir(folder)
     for file in files:
         if file[0:9] == "stream{0x": # don't rename files that have already been renamed
-            if not os.path.exists(os.path.join(folder, "stream.mv2")) and file[-3:] == "m2v":
-                os.rename(os.path.join(folder, file), os.path.join(folder, "stream.mv2"))
-            elif not (os.path.exists(os.path.join(folder, "stream0.ac3")) or os.path.exists(os.path.join(folder, "stream0.mp2"))) and file[-3:] == "ac3":
-                os.rename(os.path.join(folder, file), os.path.join(folder, "stream0.ac3"))
-            elif not (os.path.exists(os.path.join(folder, "stream0.ac3")) or os.path.exists(os.path.join(folder, "stream0.mp2"))) and file[-3:] == "mp2":
+            if not os.path.exists(os.path.join(folder, "stream.m2v")) and file[-3:] == "m2v":
+                os.rename(os.path.join(folder, file), os.path.join(folder, "stream.m2v"))
+            elif not (os.path.exists(os.path.join(folder, "stream.ac3")) or os.path.exists(os.path.join(folder, "stream0.mp2"))) and file[-3:] == "ac3":
+                os.rename(os.path.join(folder, file), os.path.join(folder, "stream.ac3"))
+            elif not (os.path.exists(os.path.join(folder, "stream.ac3")) or os.path.exists(os.path.join(folder, "stream0.mp2"))) and file[-3:] == "mp2":
                 os.rename(os.path.join(folder, file), os.path.join(folder, "stream0.mp2"))
             elif not (os.path.exists(os.path.join(folder, "stream1.ac3")) or os.path.exists(os.path.join(folder, "stream1.mp2"))) and file[-3:] == "ac3":
                 os.rename(os.path.join(folder, file), os.path.join(folder, "stream1.ac3"))
@@ -1980,7 +1980,7 @@
 
     passes = int(getText(profileNode.getElementsByTagName("passes")[0]))
 
-    command = "mythffmpeg"
+    command = "ffmpeg"
 
     if cpuCount > 1:
         command += " -threads %d" % cpuCount
@@ -2166,7 +2166,7 @@
     samplerate, channels = getAudioParams(folder)
     videores, fps, aspectratio = getVideoParams(folder)
 
-    command =  "mythffmpeg -y "
+    command =  "ffmpeg -y "
 
     if cpuCount > 1:
         command += "-threads %d " % cpuCount
@@ -2263,7 +2263,10 @@
             write("Failed to eject the disc!")
             return False
         finally:
-            os.close(f)
+            try:
+                os.close(f)
+            except NameError:
+                return True
     def waitForDrive():
         tries = 0
         while drivestatus() == CDROM.CDS_DRIVE_NOT_READY:
@@ -2444,13 +2447,13 @@
         #Generate a temp folder name for this file
         folder=getItemTempPath(filecount)
         #Process this file
-        file=os.path.join(folder,"stream.mv2")
+        file=os.path.join(folder,"stream.m2v")
         #Get size of vobfile in MBytes
         totalvideosize+=os.path.getsize(file) 
 
         #Get size of audio track 1
-        if doesFileExist(os.path.join(folder,"stream0.ac3")):
-            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.ac3")) 
+        if doesFileExist(os.path.join(folder,"stream.ac3")):
+            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream.ac3")) 
         if doesFileExist(os.path.join(folder,"stream0.mp2")):
             totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.mp2")) 
 
@@ -2478,14 +2481,14 @@
 ########################################
 #returns total size of bitrate-limited m2v files
 
-def total_mv2_brl(files,rate): 
+def total_m2v_brl(files,rate): 
     tvsize=0  
     filecount=0
     for node in files:
         filecount+=1
         folder=getItemTempPath(filecount)
         progduration=getLengthOfVideo(filecount)
-        file=os.path.join(folder,"stream.mv2")
+        file=os.path.join(folder,"stream.m2v")
         progvsize=os.path.getsize(file)
         progvbitrate=progvsize/progduration
         if progvbitrate>rate : 
@@ -2512,13 +2515,13 @@
     write( "Total video  %.2f Mb, audio %.2f Mb, menus %.2f Mb." % (totalvideosize/mega,totalaudiosize/mega,totalmenusize/mega))
 
     #Subtract the audio, menus and packaging overhead from the size of the disk (we cannot shrink this further)
-    mv2space=((dvdrsize*mega-totalmenusize)/fudge_pack)-totalaudiosize
+    m2vspace=((dvdrsize*mega-totalmenusize)/fudge_pack)-totalaudiosize
  
-    if mv2space<0:
+    if m2vspace<0:
         fatalError("Audio and menu files are too big. No room for video. Giving up!")
 
-    if totalvideosize>mv2space:
-        write( "Video files are %.1f Mb too big. Need to shrink." % ((totalvideosize - mv2space)/mega) )
+    if totalvideosize>m2vspace:
+        write( "Video files are %.1f Mb too big. Need to shrink." % ((totalvideosize - m2vspace)/mega) )
 
         if path_M2VRequantiser[0] == "":
             fatalError("M2VRequantiser is not available to resize the files.  Giving up!")
@@ -2529,7 +2532,7 @@
         for node in files:
             filecount+=1
             folder=getItemTempPath(filecount)
-            file=os.path.join(folder,"stream.mv2")
+            file=os.path.join(folder,"stream.m2v")
             vsize+=os.path.getsize(file)
             duration+=getLengthOfVideo(filecount)
 
@@ -2556,16 +2559,16 @@
             count+=1
             vrinc=vrinc*0.5
             vrtest=vrate+vrinc
-            testsize=total_mv2_brl(files,vrtest)
-            if (testsize<mv2space):
+            testsize=total_m2v_brl(files,vrtest)
+            if (testsize<m2vspace):
                 vrate=vrtest
            
-        write("vrate %.3f kb/s, testsize %.4f , mv2space %.4f Mb " % ((vrate)/1000.0, (testsize)/mega, (mv2space)/mega) )
+        write("vrate %.3f kb/s, testsize %.4f , m2vspace %.4f Mb " % ((vrate)/1000.0, (testsize)/mega, (m2vspace)/mega) )
         filecount=0
         for node in files:
             filecount+=1
             folder=getItemTempPath(filecount)
-            file=os.path.join(folder,"stream.mv2")
+            file=os.path.join(folder,"stream.m2v")
             progvsize=os.path.getsize(file)
             progduration=getLengthOfVideo(filecount)
             progvbitrate=progvsize/progduration
@@ -2574,11 +2577,11 @@
                 scalefactor=1.0+(fudge_requant*float(progvbitrate-vrate)/float(vrate))
                 if scalefactor>3.0 :
                     write( "Large shrink factor. You may not like the result! ")
-                runM2VRequantiser(os.path.join(getItemTempPath(filecount),"stream.mv2"),os.path.join(getItemTempPath(filecount),"stream.small.mv2"),scalefactor)
-                os.remove(os.path.join(getItemTempPath(filecount),"stream.mv2"))
-                os.rename(os.path.join(getItemTempPath(filecount),"stream.small.mv2"),os.path.join(getItemTempPath(filecount),"stream.mv2"))
+                runM2VRequantiser(os.path.join(getItemTempPath(filecount),"stream.m2v"),os.path.join(getItemTempPath(filecount),"stream.small.m2v"),scalefactor)
+                os.remove(os.path.join(getItemTempPath(filecount),"stream.m2v"))
+                os.rename(os.path.join(getItemTempPath(filecount),"stream.small.m2v"),os.path.join(getItemTempPath(filecount),"stream.m2v"))
     else:
-        write( "Unpackaged total %.2f Mb. About %.0f Mb will be unused." % ((allfiles/mega),(mv2space-totalvideosize)/mega))
+        write( "Unpackaged total %.2f Mb. About %.0f Mb will be unused." % ((allfiles/mega),(m2vspace-totalvideosize)/mega))
 
 #############################################################
 # Creates the DVDAuthor xml file used to create a standard DVD with menus
@@ -3180,7 +3183,7 @@
         if node.nodeName=="graphic":
             if node.attributes["filename"].value == "%movie":
                 #This is a movie preview item so we need to generate the thumbnails
-                inputfile = os.path.join(getItemTempPath(videoitem),"stream.mv2")
+                inputfile = os.path.join(getItemTempPath(videoitem),"stream.m2v")
                 outputfile = os.path.join(previewfolder, "preview-i%d-t%%1-f%%2.jpg" % itemonthispage)
                 width = getScaledAttribute(node, "w")
                 height = getScaledAttribute(node, "h")
@@ -3985,13 +3988,13 @@
     if not encodetoac3 and doesFileExist(os.path.join(folder,'stream0.mp2')):
         #don't re-encode to ac3 if the user doesn't want it
         write( "Audio track 1 is in mp2 format - NOT re-encoding to ac3")
-    elif doesFileExist(os.path.join(folder,'stream0.mp2'))==True:
+    elif doesFileExist(os.path.join(folder,'stream.mp2'))==True:
         write( "Audio track 1 is in mp2 format - re-encoding to ac3")
-        encodeAudio("ac3",os.path.join(folder,'stream0.mp2'), os.path.join(folder,'stream0.ac3'),True)
-    elif doesFileExist(os.path.join(folder,'stream0.mpa'))==True:
+        encodeAudio("ac3",os.path.join(folder,'stream.mp2'), os.path.join(folder,'stream.ac3'),True)
+    elif doesFileExist(os.path.join(folder,'stream.mpa'))==True:
         write( "Audio track 1 is in mpa format - re-encoding to ac3")
-        encodeAudio("ac3",os.path.join(folder,'stream0.mpa'), os.path.join(folder,'stream0.ac3'),True)
-    elif doesFileExist(os.path.join(folder,'stream0.ac3'))==True:
+        encodeAudio("ac3",os.path.join(folder,'stream.mpa'), os.path.join(folder,'stream.ac3'),True)
+    elif doesFileExist(os.path.join(folder,'stream.ac3'))==True:
         write( "Audio is already in ac3 format")
     else:
         fatalError("Track 1 - Unknown audio format or de-multiplex failed!")
@@ -4546,15 +4549,34 @@
                 profile = defaultEncodingProfile
 
             #do the re-encode 
-            encodeVideoToMPEG2(mediafile, os.path.join(folder, "newfile2.mpg"), video,
+#            encodeVideoToMPEG2(mediafile, os.path.join(folder, "newfile2.mpg"), video,
+            encodeVideoToMPEG2(mediafile, os.path.join(folder, os.path.basename(file.attributes["filename"].value)), video,
                             audio1, audio2, aspectratio, profile)
-            mediafile = os.path.join(folder, 'newfile2.mpg')
+#            mediafile = os.path.join(folder, 'newfile2.mpg')
+
+            if file.attributes["usecutlist"].value == "1" and getText(infoDOM.getElementsByTagName("hascutlist")[0]) == "yes":
+              # Run from local file?
+              localfile = os.path.join(folder, os.path.basename(file.attributes["filename"].value))
+              write("File has a cut list - running mythtranscode to remove unwanted segments")
+              chanid = getText(infoDOM.getElementsByTagName("chanid")[0])
+              starttime = getText(infoDOM.getElementsByTagName("starttime")[0])
+              write("About to runMythtranscode with: %s" % os.path.join(folder,'newfile3.mpg'))
+              if runMythtranscode(chanid, starttime, os.path.join(folder,'newfile3.mpg'), True, localfile):
+                write("mythtranscode success!")
+                mediafile = os.path.join(folder,'newfile3.mpg')
+              else:
+                write("Failed to run mythtranscode to remove unwanted segments")
+              mediafile = os.path.join(folder, 'newfile3.mpg')
 
             #remove the old mediafile that was run through mythtranscode
             #if it exists
             if debug_keeptempfiles==False:
                 if os.path.exists(os.path.join(folder, "newfile.mpg")):
                     os.remove(os.path.join(folder,'newfile.mpg'))
+                if os.path.exists(os.path.join(folder, "newfile2.mpg")):
+                    os.remove(os.path.join(folder,'newfile2.mpg'))
+                if os.path.exists(os.path.join(folder, "newfile3.mpg")):
+                    os.remove(os.path.join(folder,'newfile3.mpg'))
 
     # the file is now DVD compliant split it into video and audio parts
 
@@ -4588,9 +4610,9 @@
             if usebookmark == True and os.path.exists(previewImage):
                 copy(previewImage, titleImage)
             else:
-                extractVideoFrame(os.path.join(folder, "stream.mv2"), titleImage, thumboffset)
+                extractVideoFrame(os.path.join(folder, "stream.m2v"), titleImage, thumboffset)
         else:
-            extractVideoFrame(os.path.join(folder, "stream.mv2"), titleImage, thumboffset)
+            extractVideoFrame(os.path.join(folder, "stream.m2v"), titleImage, thumboffset)
 
     write( "*************************************************************")
     write( "Finished processing '%s'" % file.attributes["filename"].value)
@@ -4757,9 +4779,9 @@
             if usebookmark == True and os.path.exists(previewImage):
                 copy(previewImage, titleImage)
             else:
-                extractVideoFrame(os.path.join(folder, "stream.mv2"), titleImage, thumboffset)
+                extractVideoFrame(os.path.join(folder, "stream.m2v"), titleImage, thumboffset)
         else:
-            extractVideoFrame(os.path.join(folder, "stream.mv2"), titleImage, thumboffset)
+            extractVideoFrame(os.path.join(folder, "stream.m2v"), titleImage, thumboffset)
 
     write( "*************************************************************")
     write( "Finished processing file '%s'" % file.attributes["filename"].value)
@@ -4921,8 +4943,8 @@
                 #Multiplex this file
                 #(This also removes non-required audio feeds inside mpeg streams 
                 #(through re-multiplexing) we only take 1 video and 1 or 2 audio streams)
-                pid=multiplexMPEGStream(os.path.join(folder,'stream.mv2'),
-                        os.path.join(folder,'stream0'),
+                pid=multiplexMPEGStream(os.path.join(folder,'stream.m2v'),
+                        os.path.join(folder,'stream'),
                         os.path.join(folder,'stream1'),
                         os.path.join(folder,'final.vob'),
                         calcSyncOffset(filecount))
@@ -4936,14 +4958,14 @@
                 for node in files:
                     filecount+=1
                     folder=getItemTempPath(filecount)
-                    if os.path.exists(os.path.join(folder, "stream.mv2")):
-                        os.remove(os.path.join(folder,'stream.mv2'))
+                    if os.path.exists(os.path.join(folder, "stream.m2v")):
+                        os.remove(os.path.join(folder,'stream.m2v'))
                     if os.path.exists(os.path.join(folder, "stream0.mp2")):
                         os.remove(os.path.join(folder,'stream0.mp2'))
                     if os.path.exists(os.path.join(folder, "stream1.mp2")):
                         os.remove(os.path.join(folder,'stream1.mp2'))
-                    if os.path.exists(os.path.join(folder, "stream0.ac3")):
-                        os.remove(os.path.join(folder,'stream0.ac3'))
+                    if os.path.exists(os.path.join(folder, "stream.ac3")):
+                        os.remove(os.path.join(folder,'stream.ac3'))
                     if os.path.exists(os.path.join(folder, "stream1.ac3")):
                         os.remove(os.path.join(folder,'stream1.ac3'))
 


More information about the mythtv-users mailing list