Extensions: Various fixes and clean-ups from review
[gpodder.git] / share / gpodder / extensions / flv2mp4.py
blob21891eb6ed03be32f4588c9140ebe5df15246f57
1 # -*- coding: utf-8 -*-
2 # Put FLV files from YouTube into a MP4 container after download
3 # This requires ffmpeg to be installed. Also works as a context
4 # menu item for already-downloaded files. This does not convert
5 # the files in reality, but just swaps the container format.
7 # (c) 2011-08-05 Thomas Perl <thp.io/about>
8 # Released under the same license terms as gPodder itself.
10 import os
11 import subprocess
13 import gpodder
15 from gpodder import util
16 from gpodder import youtube
18 import logging
19 logger = logging.getLogger(__name__)
21 _ = gpodder.gettext
23 __title__ = _('Convert .flv files from YouTube to .mp4')
24 __description__ = _('Useful for playing downloaded videos on hardware players')
25 __author__ = 'Thomas Perl <thp@gpodder.org>, Bernd Schlapsi <brot@gmx.info>'
27 DefaultConfig = {
28 'context_menu': True, # Show the conversion option in the context menu
32 class gPodderExtension:
33 MIME_TYPE = 'video/x-flv'
35 def __init__(self, container):
36 self.container = container
37 self.config = self.container.config
39 # Dependency checks
40 self.container.require_command('ffmpeg')
42 def on_episode_downloaded(self, episode):
43 if youtube.is_video_link(episode.url):
44 self._convert_episode(episode)
46 def on_episodes_context_menu(self, episodes):
47 if not self.config.context_menu:
48 return None
50 if not all(e.was_downloaded(and_exists=True) for e in episodes):
51 return None
53 if not any(e.mime_type == self.MIME_TYPE for e in episodes):
54 return None
56 return [(_('Convert FLV to MP4'), self._convert_episodes)]
59 def _convert_episode(self, episode):
60 old_filename = episode.local_filename(create=False)
61 filename, ext = os.path.splitext(filename)
62 new_filename = filename + '.mp4'
64 if open(old_filename, 'rb').read(3) != 'FLV':
65 logger.debug('Not a FLV file. Ignoring.')
66 return
68 if ext.lower() == '.mp4':
69 # Move file out of place for conversion
70 tmp_filename = filename + '.flv'
71 os.rename(old_filename, tmp_filename)
72 old_filename = tmp_filename
74 cmd = ['ffmpeg',
75 '-i', old_filename,
76 '-vcodec', 'copy',
77 '-acodec', 'copy',
78 new_filename]
80 ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE,
81 stderr=subprocess.PIPE)
82 stdout, stderr = ffmpeg.communicate()
84 if ffmpeg.returncode == 0:
85 logger.info('FLV conversion successful.')
86 util.rename_episode_file(episode, new_filename)
87 os.remove(old_filename)
88 else:
89 logger.warn('Error converting file: %s / %s', stdout, stderr)
91 def _convert_episodes(self, episodes):
92 for episode in episodes:
93 self._convert_episode(episode)