Extensions: Merge audio/video converter extensions (bug 1783)
There were similar extensions which have been folded into one: - 2 similar audio extensions -> the audio_converter extension - 2 similar video extensions -> the video_converter extension With this change it's now possible to change the video output format in the advanced settings to mp4 (default) or avi.
This commit is contained in:
parent
6bf6702ccc
commit
c1c64d1c0c
|
@ -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 <brot@gmx.info>, Thomas Perl <thp@gpodder.org>'
|
||||
__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):
|
|
@ -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 <thp.io/about>
|
||||
# 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 <thp@gpodder.org>, Bernd Schlapsi <brot@gmx.info>'
|
||||
__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)
|
||||
|
|
@ -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 <brot@gmx.info>
|
||||
# (c) 2011-08-05 Thomas Perl <thp.io/about>
|
||||
# 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 <brot@gmx.info>'
|
||||
__title__ = _('Convert video files')
|
||||
__description__ = _('Transcode video files to avi/mp4/m4v')
|
||||
__authors__ = 'Thomas Perl <thp@gpodder.org>, Bernd Schlapsi <brot@gmx.info>'
|
||||
__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)
|
||||
|
Loading…
Reference in a new issue