Hello All

Attached is a patch that will allow users to select a different media
player for audio and video files.  This should be applied to the current
trunk branch in SVN.

This enhancement can also be tracked at the gPodder Bugzilla server:-

http://gpodder.thegithouse.com/show_bug.cgi?id=5

Please review and post any problems, comments or suggested improvements.

Stefan Lohmaier has requested the ability for gPodder to display PDF
files.  I will create a seperate enhancement for this and get working to
implementing it in the not too distant future.

Regards

Paul Rudkin

Index: src/gpodder/config.py
===================================================================
--- src/gpodder/config.py	(revision 528)
+++ src/gpodder/config.py	(working copy)
@@ -38,6 +38,7 @@
 gPodderSettings = {
     # General settings
     'player': ( str, 'xdg-open' ),
+    'videoplayer': (str, 'unspecified' ),
     'opml_url': ( str, 'http://gpodder.berlios.de/directory.opml' ),
     'http_proxy': ( str, '' ),
     'ftp_proxy': ( str, '' ),
Index: src/gpodder/libplayers.py
===================================================================
--- src/gpodder/libplayers.py	(revision 528)
+++ src/gpodder/libplayers.py	(working copy)
@@ -72,15 +72,16 @@
 
 
 class UserAppsReader(object):
-    def __init__( self):
+    def __init__( self, mimetype):
         self.apps = []
+	self.mimetype = mimetype
 
     def read( self):
         for dir in userappsdirs:
             if exists( dir):
                 for file in glob( dir+'/*.desktop'):
                     self.parse_and_append( file)
-        self.apps.append( UserApplication( 'Shell command', '', 'audio/*', gtk.STOCK_EXECUTE))
+        self.apps.append( UserApplication( 'Shell command', '', self.mimetype + '/*', gtk.STOCK_EXECUTE))
 
     def parse_and_append( self, filename):
         try:
@@ -93,8 +94,8 @@
             app_cmd = parser.get( sect, 'Exec')
             app_mime = parser.get( sect, 'MimeType')
             app_icon = parser.get( sect, 'Icon')
-            if app_mime.find( 'audio/') != -1:
-                log( 'Player found: %s (%s)', app_name, filename)
+            if app_mime.find( self.mimetype + '/') != -1:
+                log( 'Player found (%s): %s (%s)', self.mimetype, app_name, filename)
                 self.apps.append( UserApplication( app_name, app_cmd, app_mime, app_icon))
         except:
             return
Index: src/gpodder/libgpodder.py
===================================================================
--- src/gpodder/libgpodder.py	(revision 528)
+++ src/gpodder/libgpodder.py	(working copy)
@@ -72,6 +72,13 @@
 
         self.config = config.Config( os.path.join( gpodder_dir, 'gpodder.conf'))
 
+        # We need to make a seamless upgrade, so by default the video player is not specified
+        # so the first time this application is run it will detect this and set it to the same 
+        # as the audio player.  This keeps gPodder functionality identical to that prior to the 
+        # upgrade.   The user can then set a specific video player if they so wish.	
+        if self.config.videoplayer == 'unspecified':
+            self.config.videoplayer = self.config.player	
+
         self.__download_history = HistoryStore( os.path.join( gpodder_dir, 'download-history.txt'))
         self.__playback_history = HistoryStore( os.path.join( gpodder_dir, 'playback-history.txt'))
         self.__locked_history = HistoryStore( os.path.join( gpodder_dir, 'lock-history.txt'))
@@ -195,7 +202,15 @@
         self.history_mark_played( episode.url)
         filename = episode.local_filename()
 
-        command_line = shlex.split( util.format_desktop_command( self.config.player, filename).encode('utf-8'))
+        # Determine the file type and set the player accordingly.  
+        file_type = util.file_type_by_extension( util.file_extension_from_url( episode.url))
+
+        # Default to the audio player
+        player = self.config.player
+        if file_type == 'video':
+	        player = self.config.videoplayer
+ 
+        command_line = shlex.split( util.format_desktop_command( player, filename).encode('utf-8'))
         log( 'Command line: [ %s ]', ', '.join( [ '"%s"' % p for p in command_line ]), sender = self)
         try:
             subprocess.Popen( command_line)
Index: src/gpodder/gui.py
===================================================================
--- src/gpodder/gui.py	(revision 528)
+++ src/gpodder/gui.py	(working copy)
@@ -282,10 +282,14 @@
         self.active_channel = None
         self.channels = load_channels( load_items = False, offline = True)
 
-        # load list of user applications
-        self.user_apps_reader = UserAppsReader()
+        # load list of user applications for audio playback
+        self.user_apps_reader = UserAppsReader('audio')
         Thread( target = self.user_apps_reader.read).start()
 
+	    # load list of user applications for video playback
+        self.user_video_apps_reader = UserAppsReader('video')
+        Thread( target = self.user_video_apps_reader.read).start()
+
         # Clean up old, orphaned download files
         gl.clean_up_downloads( delete_partial = True)
 
@@ -1187,6 +1191,7 @@
     def on_itemPreferences_activate(self, widget, *args):
         prop = gPodderProperties( callback_finished = self.properties_closed)
         prop.set_uar( self.user_apps_reader)
+        prop.set_video_uar( self.user_video_apps_reader)
 
     def on_itemAddChannel_activate(self, widget, *args):
         if self.channelPaned.get_position() < 200:
@@ -1657,6 +1662,7 @@
         gl.config.connect_gtk_editable( 'http_proxy', self.httpProxy)
         gl.config.connect_gtk_editable( 'ftp_proxy', self.ftpProxy)
         gl.config.connect_gtk_editable( 'player', self.openApp)
+        gl.config.connect_gtk_editable( 'videoplayer', self.openVideoApp)
         gl.config.connect_gtk_editable( 'opml_url', self.opmlURL)
         gl.config.connect_gtk_editable( 'custom_sync_name', self.entryCustomSyncName)
         gl.config.connect_gtk_togglebutton( 'custom_sync_name_enabled', self.cbCustomSyncName)
@@ -1706,12 +1712,19 @@
 
         # setup cell renderers
         cellrenderer = gtk.CellRendererPixbuf()
-        self.comboPlayerApp.pack_start( cellrenderer, False)
-        self.comboPlayerApp.add_attribute( cellrenderer, 'pixbuf', 2)
+        self.comboAudioPlayerApp.pack_start( cellrenderer, False)
+        self.comboAudioPlayerApp.add_attribute( cellrenderer, 'pixbuf', 2)
         cellrenderer = gtk.CellRendererText()
-        self.comboPlayerApp.pack_start( cellrenderer, True)
-        self.comboPlayerApp.add_attribute( cellrenderer, 'markup', 0)
+        self.comboAudioPlayerApp.pack_start( cellrenderer, True)
+        self.comboAudioPlayerApp.add_attribute( cellrenderer, 'markup', 0)
 
+        cellrenderer = gtk.CellRendererPixbuf()
+        self.comboVideoPlayerApp.pack_start( cellrenderer, False)
+        self.comboVideoPlayerApp.add_attribute( cellrenderer, 'pixbuf', 2)
+        cellrenderer = gtk.CellRendererText()
+        self.comboVideoPlayerApp.pack_start( cellrenderer, True)
+        self.comboVideoPlayerApp.add_attribute( cellrenderer, 'markup', 0)
+
         self.ipodIcon.set_from_icon_name( 'gnome-dev-ipod', gtk.ICON_SIZE_BUTTON)
 
     def update_mountpoint( self, ipod):
@@ -1721,13 +1734,19 @@
             self.iPodMountpoint.set_label( ipod.mount_point)
     
     def set_uar( self, uar):
-        self.comboPlayerApp.set_model( uar.get_applications_as_model())
+        self.comboAudioPlayerApp.set_model( uar.get_applications_as_model())
         # try to activate an item
-        index = self.find_active()
-        self.comboPlayerApp.set_active( index)
+        index = self.find_active_audio_app()
+        self.comboAudioPlayerApp.set_active( index)
+
+    def set_video_uar( self, uar):
+        self.comboVideoPlayerApp.set_model( uar.get_applications_as_model())
+        # try to activate an item
+        index = self.find_active_video_app()
+        self.comboVideoPlayerApp.set_active( index)
     
-    def find_active( self):
-        model = self.comboPlayerApp.get_model()
+    def find_active_audio_app( self):
+        model = self.comboAudioPlayerApp.get_model()
         iter = model.get_iter_first()
         index = 0
         while iter != None:
@@ -1738,6 +1757,19 @@
             index = index + 1
         # return last item = custom command
         return index-1
+
+    def find_active_video_app( self):
+        model = self.comboVideoPlayerApp.get_model()
+        iter = model.get_iter_first()
+        index = 0
+        while iter != None:
+            command = model.get_value( iter, 1)
+            if command == self.openVideoApp.get_text():
+                return index
+            iter = model.iter_next( iter)
+            index = index + 1
+        # return last item = custom command
+        return index-1
     
     def set_download_dir( self, new_download_dir, event = None):
         gl = gPodderLib()
@@ -1772,10 +1804,10 @@
     def on_gPodderProperties_destroy(self, widget, *args):
         self.on_btnOK_clicked( widget, *args)
 
-    def on_comboPlayerApp_changed(self, widget, *args):
+    def on_comboAudioPlayerApp_changed(self, widget, *args):
         # find out which one
-        iter = self.comboPlayerApp.get_active_iter()
-        model = self.comboPlayerApp.get_model()
+        iter = self.comboAudioPlayerApp.get_active_iter()
+        model = self.comboAudioPlayerApp.get_model()
         command = model.get_value( iter, 1)
         if command == '':
             self.openApp.set_sensitive( True)
@@ -1787,6 +1819,21 @@
             self.openApp.hide()
             self.labelCustomCommand.hide()
 
+    def on_comboVideoPlayerApp_changed(self, widget, *args):
+        # find out which one
+        iter = self.comboVideoPlayerApp.get_active_iter()
+        model = self.comboVideoPlayerApp.get_model()
+        command = model.get_value( iter, 1)
+        if command == '':
+            self.openVideoApp.set_sensitive( True)
+            self.openVideoApp.show()
+            self.labelCustomCommand.show()
+        else:
+            self.openVideoApp.set_text( command)
+            self.openVideoApp.set_sensitive( False)
+            self.openVideoApp.hide()
+            self.labelCustomCommand.hide()
+
     def on_cbMaxDownloads_toggled(self, widget, *args):
         self.spinMaxDownloads.set_sensitive( self.cbMaxDownloads.get_active())
 
Index: data/gpodder.glade
===================================================================
--- data/gpodder.glade	(revision 528)
+++ data/gpodder.glade	(working copy)
@@ -368,7 +368,7 @@
 		      <property name="visible">True</property>
 		      <property name="label" translatable="yes">_Close</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_gPodder_delete_event" last_modification_time="Sat, 29 Oct 2005 41:54:31 GMT"/>
+		      <signal name="activate" handler="on_gPodder_delete_event" last_modification_time="Sun, 30 Oct 2005 17:54:31 GMT"/>
 		      <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
@@ -716,8 +716,8 @@
 		      <child internal-child="image">
 			<widget class="GtkImage" id="image2927">
 			  <property name="visible">True</property>
+			  <property name="icon_size">1</property>
 			  <property name="icon_name">bug-buddy</property>
-			  <property name="icon_size">1</property>
 			  <property name="xalign">0.5</property>
 			  <property name="yalign">0.5</property>
 			  <property name="xpad">0</property>
@@ -2123,7 +2123,7 @@
 	    <widget class="GtkTable" id="table2">
 	      <property name="border_width">10</property>
 	      <property name="visible">True</property>
-	      <property name="n_rows">7</property>
+	      <property name="n_rows">10</property>
 	      <property name="n_columns">3</property>
 	      <property name="homogeneous">False</property>
 	      <property name="row_spacing">5</property>
@@ -2180,7 +2180,7 @@
 	      <child>
 		<widget class="GtkLabel" id="label74">
 		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Media Player&lt;/b&gt;</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Audio Media Player&lt;/b&gt;</property>
 		  <property name="use_underline">False</property>
 		  <property name="use_markup">True</property>
 		  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -2209,7 +2209,7 @@
 		<widget class="GtkImage" id="image2411">
 		  <property name="visible">True</property>
 		  <property name="icon_size">6</property>
-		  <property name="icon_name">applications-multimedia</property>
+		  <property name="icon_name">audio-x-generic</property>
 		  <property name="xalign">0.5</property>
 		  <property name="yalign">0.5</property>
 		  <property name="xpad">6</property>
@@ -2246,19 +2246,19 @@
 		<packing>
 		  <property name="left_attach">0</property>
 		  <property name="right_attach">3</property>
-		  <property name="top_attach">4</property>
-		  <property name="bottom_attach">5</property>
+		  <property name="top_attach">7</property>
+		  <property name="bottom_attach">8</property>
 		  <property name="x_options">fill</property>
 		  <property name="y_options"></property>
 		</packing>
 	      </child>
 
 	      <child>
-		<widget class="GtkComboBox" id="comboPlayerApp">
+		<widget class="GtkComboBox" id="comboAudioPlayerApp">
 		  <property name="visible">True</property>
 		  <property name="add_tearoffs">False</property>
 		  <property name="focus_on_click">True</property>
-		  <signal name="changed" handler="on_comboPlayerApp_changed" last_modification_time="Wed, 29 Mar 2006 21:25:13 GMT"/>
+		  <signal name="changed" handler="on_comboAudioPlayerApp_changed" last_modification_time="Sat, 19 Jan 2008 12:49:48 GMT"/>
 		</widget>
 		<packing>
 		  <property name="left_attach">1</property>
@@ -2282,8 +2282,8 @@
 		<packing>
 		  <property name="left_attach">0</property>
 		  <property name="right_attach">1</property>
-		  <property name="top_attach">5</property>
-		  <property name="bottom_attach">6</property>
+		  <property name="top_attach">8</property>
+		  <property name="bottom_attach">9</property>
 		  <property name="x_padding">6</property>
 		  <property name="x_options">fill</property>
 		  <property name="y_options">fill</property>
@@ -2303,23 +2303,135 @@
 		<packing>
 		  <property name="left_attach">1</property>
 		  <property name="right_attach">3</property>
+		  <property name="top_attach">8</property>
+		  <property name="bottom_attach">9</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHSeparator" id="hseparator9">
+		  <property name="visible">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
+		  <property name="top_attach">6</property>
+		  <property name="bottom_attach">7</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options">fill</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="openVideoApp">
+		  <property name="sensitive">False</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">2</property>
+		  <property name="right_attach">3</property>
 		  <property name="top_attach">5</property>
 		  <property name="bottom_attach">6</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label115">
+		  <property name="label" translatable="yes">Command line:</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">5</property>
+		  <property name="bottom_attach">6</property>
 		  <property name="x_options">fill</property>
 		  <property name="y_options"></property>
 		</packing>
 	      </child>
 
 	      <child>
-		<widget class="GtkHSeparator" id="hseparator9">
+		<widget class="GtkImage" id="image2928">
 		  <property name="visible">True</property>
+		  <property name="icon_size">6</property>
+		  <property name="icon_name">video-x-generic</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">6</property>
+		  <property name="ypad">0</property>
 		</widget>
 		<packing>
 		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">4</property>
+		  <property name="bottom_attach">6</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options">fill</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkComboBox" id="comboVideoPlayerApp">
+		  <property name="visible">True</property>
+		  <property name="add_tearoffs">False</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="changed" handler="on_comboVideoPlayerApp_changed" last_modification_time="Sat, 19 Jan 2008 12:49:01 GMT"/>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
 		  <property name="right_attach">3</property>
+		  <property name="top_attach">4</property>
+		  <property name="bottom_attach">5</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options">fill</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label114">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Video Media Player&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">3</property>
 		  <property name="top_attach">3</property>
 		  <property name="bottom_attach">4</property>
-		  <property name="y_padding">3</property>
 		  <property name="x_options">fill</property>
 		  <property name="y_options"></property>
 		</packing>
_______________________________________________
gpodder-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/gpodder-devel

Reply via email to