boralyl avatar boralyl committed 8d0bf16 Draft

Updated the mkiso subproject. Also changed the way the progress dialog works so that it updates in realtime, instead of using random numbers.

Comments (0)

Files changed (4)

 import wx
 
 from mkiso.mkiso import ISOCreator
+from mkiso.utils import get_duration
 
 from ui import MakeIsoUi
 
         """
         Displays dialog and runs conversion to ISO
         """
+        maxval = get_duration(self.path)
         self.progress_dlg = wx.ProgressDialog("Making ISO", "Converting",
-            maximum=100, parent=self,
+            maximum=maxval, parent=self,
             style=wx.PD_CAN_ABORT|wx.PD_APP_MODAL)
         self.run_makeiso()
         self.progress_dlg.Update(100, "Done!")
         """
         Runs the makeiso module
         """
-        make_iso = ISOCreator([self.path], '~/file.iso', True, 5)
-        self.progress_dlg.Update(25, "Converting to MPEG2...")
+        output_file = self.path.split('.')[:-1][0] + '.iso'
+        make_iso = ISOCreator([self.path], output_file, True, 5)
+        self.progress_dlg.Update(0, "Converting to MPEG2...")
         for video in make_iso.video_files:
             video = os.path.abspath(video)
-            make_iso.convert_video(video)
-        self.progress_dlg.Update(65, "Creating DVD titles...")
+            make_iso.convert_video(video, self.update_progress)
         make_iso.dvdauthor()
-        self.progress_dlg.Update(80, "Creating DVD ISO Image...")
         make_iso.mkiso()
         make_iso.cleanup()
 
+    def update_progress(self, value):
+        """
+        Updates the progress dialog status.
+        """
+        self.progress_dlg.Update(value)
+
     def run(self):
         app = wx.App()
         app.MainLoop()
 
+
 if __name__ == '__main__':
     app = MakeIsoAppRunner()
 
 import shutil
 import subprocess
 
-from utils import get_chapters, parse_args, run_cmd
+from progressbar import Bar, ETA, Percentage, ProgressBar
+
+from utils import get_chapters, get_duration, parse_args, run_cmd
 from videotypes import AviFile, InvalidVideoFormatError, Mp4File, MkvFile
 
 
         self.converted_videos = []
         self.verbose = verbose
         self.chapters = chapters
+        self.progress_bar = None
         os.putenv("VIDEO_FORMAT", "NTSC")
 
-    def convert_video(self, video):
+    def convert_video(self, video, callback=None):
         """
         Converts videos into DVD MPEG2 formats
         """
-        if self.verbose:
-            print "Converting %s to MPEG2..." % (video, )
         ext = video.split('.')[-1]
         mpg_file = ".".join(video.split('.')[:-1]) + ".mpg"
+        duration = get_duration(video)
+        convert = True
         if ext not in VALID_EXTENSIONS:
             raise InvalidVideoFormatError(video)
         elif ext == 'avi':
-            avi = AviFile(video)
-            success = avi.convert()
-            if success:
-                self.converted_videos.append(mpg_file)
+            video_file = AviFile(video)
         elif ext == 'mkv':
-            mkv = MkvFile(video)
-            success = mkv.convert()
-            if success:
-                self.converted_videos.append(mpg_file)
+            video_file = MkvFile(video)
         elif ext == 'mpg':
             self.converted_videos.append(video)
+            convert = False
         elif ext == 'mp4':
-            mp4 = Mp4File(video)
-            success = mp4.convert()
-            if success:
-                self.converted_videos.append(mpg_file)
+            video_file = Mp4File(video)
+
+        if convert:
+            if not callback:
+                label = "Converting %s to MPEG2: " % (video, )
+                self.setup_progress_bar(label, duration)
+                self.progress_bar.start()
+                video_file.convert(self.update_progress_bar)
+                self.progress_bar.finish()
+            else:
+                video_file.convert(callback)
+            self.converted_videos.append(mpg_file)
 
     def dvdauthor(self):
         """
         self.mkiso()
         self.cleanup()
 
+    def setup_progress_bar(self, task_label, maxval=100):
+        """
+        Creates a progress bar for the current task
+        """
+        if not self.progress_bar:
+            widgets = [task_label, Percentage(), ' ', Bar(), ' ', ETA()]
+            self.progress_bar = ProgressBar(widgets=widgets, maxval=maxval)
+
+    def update_progress_bar(self, value):
+        """
+        Updates the current progress bar
+        """
+        self.progress_bar.update(value)
+
     def cleanup(self):
         """
         Removed mpg files and any other non-necessary files created
             print "Cleaning up files..."
         shutil.rmtree("/tmp/DVD")
         os.remove("/tmp/dvd.xml")
+        # delete any mpg files created
+        for video in self.converted_videos:
+            os.remove(video)
 
 
 def main():
 import argparse
+import re
 import subprocess
 
 
         return False
     else:
         return True
+
+
+def get_duration(file_path):
+    """
+    Gets the duration of a video file using ffmpeg
+    returns The total number of seconds. i.e.
+    It wil return 243 for a video of 4 minutes, 3 seconds
+    """
+    cmd = "ffmpeg -i %s" % (file_path, )
+    output = run_cmd(cmd, True)
+    match = re.search('Duration: ([\d]{2}:[\d]{2}:[\d]{2})', output)
+    if match:
+        hours, minutes, seconds = match.groups()[0].split(':')
+        total_seconds = (int(hours) * 60 * 60) + (int(minutes) * 60) + int(seconds)
+        return total_seconds
+

mkiso/videotypes.py

 responsible for defining how it converts it's filetype to a MPEG2 compaitable
 format.
 """
+import pexpect
 import re
 
-from utils import run_cmd
+from progressbar import AnimatedMarker, Bar, ETA, Percentage, ProgressBar
+
+from utils import get_duration, run_cmd
 
 
 class InvalidVideoFormatError(Exception):
     def get_convert_cmd(self):
         pass
 
-    def convert(self):
-        return run_cmd(self.get_convert_cmd())
+    def convert(self, callback=None):
+        """
+        Runs the convert command
+        """
+        thread = pexpect.spawn(self.get_convert_cmd())
+        compiled = thread.compile_pattern_list([
+            pexpect.EOF,
+            ".+time=(\d+)",
+        '(.+)'
+        ])
+        while True:
+            index = thread.expect_list(compiled, timeout=None)
+            if index == 0:
+                break
+            elif index == 1:
+                seconds = thread.match.group(1)
+                if callback:
+                    callback(int(seconds))
+                thread.close
 
 
 class MkvFile(VideoFile):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.