diff --git a/share/gpodder/extensions/m4a_converter.py b/share/gpodder/extensions/audio_converter.py similarity index 63% rename from share/gpodder/extensions/m4a_converter.py rename to share/gpodder/extensions/audio_converter.py index 0674cd3a..9ea85061 100644 --- a/share/gpodder/extensions/m4a_converter.py +++ b/share/gpodder/extensions/audio_converter.py @@ -17,8 +17,8 @@ logger = logging.getLogger(__name__) _ = gpodder.gettext -__title__ = _('Convert M4A audio to MP3 or OGG') -__description__ = _('Transcode .m4a files to .mp3 or .ogg using ffmpeg') +__title__ = _('Convert audio files') +__description__ = _('Transcode audio files to mp3/ogg') __authors__ = 'Bernd Schlapsi , Thomas Perl ' __category__ = 'post-download' @@ -29,12 +29,14 @@ DefaultConfig = { } class gPodderExtension: - MIME_TYPES = ['audio/x-m4a', 'audio/mp4', 'audio/mp4a-latm'] - EXT = '.m4a' - CMD = {'avconv': ['-i', '%(old_file)s', '-q:a', '2', '-id3v2_version', - '3', '-write_id3v1', '1', '%(new_file)s'], - 'ffmpeg': ['-i', '%(old_file)s', '-q:a', '2', '-id3v2_version', - '3', '-write_id3v1', '1', '%(new_file)s'] + MIME_TYPES = ('audio/x-m4a', 'audio/mp4', 'audio/mp4a-latm', 'audio/ogg', ) + EXT = ('.m4a', '.ogg') + CMD = {'avconv': {'.mp3': ['-i', '%(old_file)s', '-q:a', '2', '-id3v2_version', '3', '-write_id3v1', '1', '%(new_file)s'], + '.ogg': ['-i', '%(old_file)s', '-q:a', '2', '%(new_file)s'] + }, + 'ffmpeg': {'.mp3': ['-i', '%(old_file)s', '-q:a', '2', '-id3v2_version', '3', '-write_id3v1', '1', '%(new_file)s'], + '.ogg': ['-i', '%(old_file)s', '-q:a', '2', '%(new_file)s'] + } } def __init__(self, container): @@ -45,18 +47,23 @@ class gPodderExtension: self.command = self.container.require_any_command(['avconv', 'ffmpeg']) # extract command without extension (.exe on Windows) from command-string - command_without_ext = os.path.basename(os.path.splitext(self.command)[0]) - self.command_param = self.CMD[command_without_ext] + self.command_without_ext = os.path.basename(os.path.splitext(self.command)[0]) def on_episode_downloaded(self, episode): self._convert_episode(episode) + + def _get_new_extension(self): + return ('.ogg' if self.config.use_ogg else '.mp3') - def _check_mp4(self, episode): + def _check_source(self, episode): + if episode.extension() == self._get_new_extension(): + return False + if episode.mime_type in self.MIME_TYPES: return True # Also check file extension (bug 1770) - if episode.extension() == self.EXT: + if episode.extension() in self.EXT: return True return False @@ -68,7 +75,7 @@ class gPodderExtension: if not all(e.was_downloaded(and_exists=True) for e in episodes): return None - if not any(self._check_mp4(episode) for episode in episodes): + if not any(self._check_source(episode) for episode in episodes): return None target_format = ('OGG' if self.config.use_ogg else 'MP3') @@ -77,22 +84,19 @@ class gPodderExtension: return [(menu_item, self._convert_episodes)] def _convert_episode(self, episode): - old_filename = episode.local_filename(create=False) - - if not self._check_mp4(episode): + if not self._check_source(episode): return - if self.config.use_ogg: - extension = '.ogg' - else: - extension = '.mp3' - + new_extension = self._get_new_extension() + old_filename = episode.local_filename(create=False) filename, old_extension = os.path.splitext(old_filename) - new_filename = filename + extension + new_filename = filename + new_extension + cmd_param = self.CMD[self.command_without_ext][new_extension] cmd = [self.command] + \ [param % {'old_file': old_filename, 'new_file': new_filename} - for param in self.command_param] + for param in cmd_param] + ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = ffmpeg.communicate() @@ -101,10 +105,10 @@ class gPodderExtension: util.rename_episode_file(episode, new_filename) os.remove(old_filename) - logger.info('Converted M4A file.') + logger.info('Converted audio file to %(format)s.' % {'format': new_extension}) gpodder.user_extensions.on_notification_show(_('File converted'), episode.title) else: - logger.warn('Error converting file: %s / %s', stdout, stderr) + logger.warn('Error converting audio file: %s / %s', stdout, stderr) gpodder.user_extensions.on_notification_show(_('Conversion failed'), episode.title) def _convert_episodes(self, episodes): diff --git a/share/gpodder/extensions/flv2mp4.py b/share/gpodder/extensions/flv2mp4.py deleted file mode 100644 index d559d745..00000000 --- a/share/gpodder/extensions/flv2mp4.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -# Put FLV files from YouTube into a MP4 container after download -# This requires ffmpeg to be installed. Also works as a context -# menu item for already-downloaded files. This does not convert -# the files in reality, but just swaps the container format. -# -# (c) 2011-08-05 Thomas Perl -# Released under the same license terms as gPodder itself. - -import os -import subprocess - -import gpodder - -from gpodder import util -from gpodder import youtube - -import logging -logger = logging.getLogger(__name__) - -_ = gpodder.gettext - -__title__ = _('Convert .flv files from YouTube to .mp4') -__description__ = _('Useful for playing downloaded videos on hardware players') -__authors__ = 'Thomas Perl , Bernd Schlapsi ' -__category__ = 'post-download' - -DefaultConfig = { - 'context_menu': True, # Show the conversion option in the context menu -} - - -class gPodderExtension: - MIME_TYPE = 'video/x-flv' - - def __init__(self, container): - self.container = container - self.config = self.container.config - - # Dependency checks - self.container.require_command('ffmpeg') - - def on_episode_downloaded(self, episode): - if youtube.is_video_link(episode.url): - self._convert_episode(episode) - - def on_episodes_context_menu(self, episodes): - if not self.config.context_menu: - return None - - if not all(e.was_downloaded(and_exists=True) for e in episodes): - return None - - if not any(e.mime_type == self.MIME_TYPE for e in episodes): - return None - - return [(_('Convert FLV to MP4'), self._convert_episodes)] - - - def _convert_episode(self, episode): - old_filename = episode.local_filename(create=False) - filename, ext = os.path.splitext(old_filename) - new_filename = filename + '.mp4' - - if open(old_filename, 'rb').read(3) != 'FLV': - logger.debug('Not a FLV file. Ignoring.') - return - - if ext.lower() == '.mp4': - # Move file out of place for conversion - tmp_filename = filename + '.flv' - os.rename(old_filename, tmp_filename) - old_filename = tmp_filename - - cmd = ['ffmpeg', - '-i', old_filename, - '-vcodec', 'copy', - '-acodec', 'copy', - new_filename] - - ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - stdout, stderr = ffmpeg.communicate() - - if ffmpeg.returncode == 0: - util.rename_episode_file(episode, new_filename) - os.remove(old_filename) - - logger.info('FLV conversion successful.') - gpodder.user_extensions.on_notification_show(_('File converted'), episode.title) - else: - logger.warn('Error converting file: %s / %s', stdout, stderr) - gpodder.user_extensions.on_notification_show(_('Conversion failed'), episode.title) - - def _convert_episodes(self, episodes): - for episode in episodes: - self._convert_episode(episode) - diff --git a/share/gpodder/extensions/ogg2mp3_converter.py b/share/gpodder/extensions/video_converter.py similarity index 51% rename from share/gpodder/extensions/ogg2mp3_converter.py rename to share/gpodder/extensions/video_converter.py index 3deb2e19..53193ca9 100644 --- a/share/gpodder/extensions/ogg2mp3_converter.py +++ b/share/gpodder/extensions/video_converter.py @@ -1,39 +1,40 @@ # -*- coding: utf-8 -*- -# Convertes ogg audio files to mp3 +# Convertes video files to avi or mp4 # This requires ffmpeg to be installed. Also works as a context # menu item for already-downloaded files. # -# (c) 2012-12-28 Bernd Schlapsi +# (c) 2011-08-05 Thomas Perl # Released under the same license terms as gPodder itself. import os import subprocess import gpodder + from gpodder import util +from gpodder import youtube import logging logger = logging.getLogger(__name__) _ = gpodder.gettext -__title__ = _('Convert OGG audio to MP3') -__description__ = _('Transcode .ogg files to .mp3 using ffmpeg') -__authors__ = 'Bernd Schlapsi ' +__title__ = _('Convert video files') +__description__ = _('Transcode video files to avi/mp4/m4v') +__authors__ = 'Thomas Perl , Bernd Schlapsi ' __category__ = 'post-download' - DefaultConfig = { + 'output_format': 'mp4', # At the moment we support/test only mp4, m4v and avi 'context_menu': True, # Show the conversion option in the context menu } + class gPodderExtension: - MIME_TYPES = ('audio/ogg',) - TARGET_EXT = '.mp3' - CMD = {'avconv': ['-i', '%(old_file)s', '-q:a', '2', '-id3v2_version', - '3', '-write_id3v1', '1', '%(new_file)s'], - 'ffmpeg': ['-i', '%(old_file)s', '-q:a', '2', '-id3v2_version', - '3', '-write_id3v1', '1', '%(new_file)s'] + MIME_TYPES = ('video/mp4', 'video/m4v', 'video/x-flv', ) + EXT = ('.mp4', '.m4v', '.flv', ) + CMD = {'avconv': ['-i', '%(old_file)s', '-codec', 'copy', '%(new_file)s'], + 'ffmpeg': ['-i', '%(old_file)s', '-codec', 'copy', '%(new_file)s'] } def __init__(self, container): @@ -48,7 +49,27 @@ class gPodderExtension: self.command_param = self.CMD[command_without_ext] def on_episode_downloaded(self, episode): - self.convert_episode(episode) + self._convert_episode(episode) + + def _get_new_extension(self): + ext = self.config.output_format + if not ext.startswith('.'): + ext = '.' + ext + + return ext + + def _check_source(self, episode): + if episode.extension() == self._get_new_extension(): + return False + + if episode.mime_type in self.MIME_TYPES: + return True + + # Also check file extension (bug 1770) + if episode.extension() in self.EXT: + return True + + return False def on_episodes_context_menu(self, episodes): if not self.config.context_menu: @@ -57,19 +78,22 @@ class gPodderExtension: if not all(e.was_downloaded(and_exists=True) for e in episodes): return None - if not any(e.mime_type in self.MIME_TYPES for e in episodes): + if not any(self._check_source(episode) for episode in episodes): return None - return [('Convert to MP3', self.convert_episodes)] + menu_item = _('Convert to %(format)s') % {'format': self.config.output_format} - def convert_episode(self, episode): - if episode.mime_type not in self.MIME_TYPES: + return [(menu_item, self._convert_episodes)] + + def _convert_episode(self, episode): + if not self._check_source(episode): return + new_extension = self._get_new_extension() old_filename = episode.local_filename(create=False) filename, old_extension = os.path.splitext(old_filename) - new_filename = filename + self.TARGET_EXT - + new_filename = filename + new_extension + cmd = [self.command] + \ [param % {'old_file': old_filename, 'new_file': new_filename} for param in self.command_param] @@ -81,13 +105,13 @@ class gPodderExtension: util.rename_episode_file(episode, new_filename) os.remove(old_filename) - logger.info('Converted OGG file to MP3.') - gpodder.user_extensions.on_notification_show(_('File converted from ogg to mp3'), episode.title) + logger.info('Converted video file to %(format)s.' % {'format': self.config.output_format}) + gpodder.user_extensions.on_notification_show(_('File converted'), episode.title) else: - logger.warn('Error converting file from ogg to mp3: %s / %s', stdout, stderr) - gpodder.user_extensions.on_notification_show(_('Conversion failed from ogg to mp3'), episode.title) + logger.warn('Error converting video file: %s / %s', stdout, stderr) + gpodder.user_extensions.on_notification_show(_('Conversion failed'), episode.title) - def convert_episodes(self, episodes): + def _convert_episodes(self, episodes): for episode in episodes: - self.convert_episode(episode) + self._convert_episode(episode)