# -*- coding: utf-8 -*- # Requirements: apt-get install python-kaa-metadata ffmpeg python-dbus # To use, copy it as a Python script into ~/.config/gpodder/extensions/rockbox_mp4_convert.py # See the module "gpodder.extensions" for a description of when each extension # gets called and what the parameters of each extension are. # Based on Rename files after download based on the episode title # And patch in Bug https://bugs.gpodder.org/show_bug.cgi?id=1263 # Copyright (c) 2011-04-06 Guy Sheffer # Copyright (c) 2011-04-04 Thomas Perl # Licensed under the same terms as gPodder itself import logging import os import shlex import subprocess import kaa.metadata import gpodder from gpodder import util logger = logging.getLogger(__name__) _ = gpodder.gettext __title__ = _('Convert video files to MP4 for Rockbox') __description__ = _('Converts all videos to a Rockbox-compatible format') __authors__ = 'Guy Sheffer , Thomas Perl , Bernd Schlapsi ' __category__ = 'post-download' DefaultConfig = { 'device_height': 176.0, 'device_width': 224.0, 'ffmpeg_options': '-vcodec mpeg2video -b 500k -ab 192k -ac 2 -ar 44100 -acodec libmp3lame', } ROCKBOX_EXTENSION = "mpg" EXTENTIONS_TO_CONVERT = ['.mp4', "." + ROCKBOX_EXTENSION] FFMPEG_CMD = 'ffmpeg -y -i "%(from)s" -s %(width)sx%(height)s %(options)s "%(to)s"' class gPodderExtension: def __init__(self, container): self.container = container program = shlex.split(FFMPEG_CMD)[0] if not util.find_command(program): raise ImportError("Couldn't find program '%s'" % program) def on_load(self): logger.info('Extension "%s" is being loaded.' % __title__) def on_unload(self): logger.info('Extension "%s" is being unloaded.' % __title__) def on_episode_downloaded(self, episode): current_filename = episode.local_filename(False) converted_filename = self._convert_mp4(episode, current_filename) if converted_filename is not None: util.rename_episode_file(episode, converted_filename) os.remove(current_filename) logger.info('Conversion for %s was successfully' % current_filename) gpodder.user_extensions.on_notification_show(_('File converted'), episode.title) def _get_rockbox_filename(self, origin_filename): if not os.path.exists(origin_filename): logger.info("File '%s' don't exists." % origin_filename) return None dirname = os.path.dirname(origin_filename) filename = os.path.basename(origin_filename) basename, ext = os.path.splitext(filename) if ext not in EXTENTIONS_TO_CONVERT: logger.info("Ignore file with file-extension %s." % ext) return None if filename.endswith(ROCKBOX_EXTENSION): new_filename = "%s-convert.%s" % (basename, ROCKBOX_EXTENSION) else: new_filename = "%s.%s" % (basename, ROCKBOX_EXTENSION) return os.path.join(dirname, new_filename) def _calc_resolution(self, video_width, video_height, device_width, device_height): if video_height is None: return None width_ratio = device_width // video_width height_ratio = device_height // video_height dest_width = device_width dest_height = width_ratio * video_height if dest_height > device_height: dest_width = height_ratio * video_width dest_height = device_height return (int(round(dest_width)), round(int(dest_height))) def _convert_mp4(self, episode, from_file): """Convert MP4 file to rockbox mpg file""" # generate new filename and check if the file already exists to_file = self._get_rockbox_filename(from_file) if to_file is None: return None if os.path.isfile(to_file): return to_file logger.info("Converting: %s", from_file) gpodder.user_extensions.on_notification_show("Converting", episode.title) # calculationg the new screen resolution info = kaa.metadata.parse(from_file) resolution = self._calc_resolution( info.video[0].width, info.video[0].height, self.container.config.device_width, self.container.config.device_height ) if resolution is None: logger.error("Error calculating the new screen resolution") return None convert_command = FFMPEG_CMD % { 'from': from_file, 'to': to_file, 'width': str(resolution[0]), 'height': str(resolution[1]), 'options': self.container.config.ffmpeg_options } if gpodder.ui.win32: p = util.Popen(shlex.split(convert_command)) p.wait() stdout, stderr = ("",) * 2 else: process = util.Popen(shlex.split(convert_command), stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() if process.returncode != 0: logger.error(stderr) return None gpodder.user_extensions.on_notification_show("Converting finished", episode.title) return to_file