Extensions: Various fixes and clean-ups from review
[gpodder.git] / share / gpodder / extensions / m4a_converter.py
blob07e5acab1267bcb6624c838bf7eb5b929ead6d21
1 # -*- coding: utf-8 -*-
2 # Convertes m4a audio files to mp3
3 # This requires ffmpeg to be installed. Also works as a context
4 # menu item for already-downloaded files.
6 # (c) 2011-11-23 Bernd Schlapsi <brot@gmx.info>
7 # Released under the same license terms as gPodder itself.
9 import os
10 import subprocess
12 import gpodder
14 import logging
15 logger = logging.getLogger(__name__)
17 _ = gpodder.gettext
19 __title__ = _('Convert M4A audio to MP3 or OGG')
20 __description__ = _('Transcode .m4a files to .mp3 or .ogg using ffmpeg')
21 __author__ = 'Bernd Schlapsi <brot@gmx.info>, Thomas Perl <thp@gpodder.org>'
24 DefaultConfig = {
25 'use_ogg': False, # Set to True to convert to .ogg (otherwise .mp3)
26 'context_menu': True, # Show the conversion option in the context menu
29 class gPodderExtension:
30 MIME_TYPES = ['audio/x-m4a', 'audio/mp4']
32 def __init__(self, container):
33 self.container = container
34 self.config = self.container.config
36 # Dependency checks
37 self.container.require_command('ffmpeg')
39 def on_episode_downloaded(self, episode):
40 self._convert_episode(episode)
42 def on_episodes_context_menu(self, episodes):
43 if not self.config.context_menu:
44 return None
46 if not all(e.was_downloaded(and_exists=True) for e in episodes):
47 return None
49 if not any(e.mime_type in self.MIME_TYPES for e in episodes):
50 return None
52 target_format = ('OGG' if self.config.use_ogg else 'MP3')
53 menu_item = _('Convert to %(format)s') % {'format': target_format}
55 return [(menu_item, self._convert_episodes)]
57 def _convert_episode(self, episode):
58 if episode.mime_type not in self.MIME_TYPES:
59 return
61 if self.config.use_ogg:
62 extension = '.ogg'
63 else:
64 extension = '.mp3'
66 old_filename = episode.local_filename(create=False)
67 filename, _ = os.path.splitext(old_filename)
68 new_filename = filename + extension
70 cmd = ['ffmpeg', '-i', old_filename, '-sameq', new_filename]
71 ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE,
72 stderr=subprocess.PIPE)
73 stdout, stderr = ffmpeg.communicate()
75 if ffmpeg.returncode == 0:
76 logger.info('Converted M4A file.')
77 gpodder.user_extensions.on_notification_show(_('File converted'),
78 episode)
79 else:
80 logger.warn('Error converting file: %s / %s', stdout, stderr)
81 gpodder.user_extensions.on_notification_show(_('Conversion failed'),
82 episode)
84 def _convert_episodes(self, episodes):
85 for episode in episodes:
86 self._convert_episode(episode)