~ubuntu-branches/ubuntu/vivid/gpodder/vivid-proposed

« back to all changes in this revision

Viewing changes to share/gpodder/extensions/video_converter.py

  • Committer: Package Import Robot
  • Author(s): tony mancill
  • Date: 2013-04-12 22:07:02 UTC
  • mfrom: (5.2.27 sid)
  • Revision ID: package-import@ubuntu.com-20130412220702-mux8v9r8zt2jin0x
Tags: 3.5.1-1
* New upstream release.
* d/control: declare versioned dependency on python-gtk2 (>= 2.16)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
# Convertes video files to avi or mp4
 
3
# This requires ffmpeg to be installed. Also works as a context
 
4
# menu item for already-downloaded files.
 
5
#
 
6
# (c) 2011-08-05 Thomas Perl <thp.io/about>
 
7
# Released under the same license terms as gPodder itself.
 
8
 
 
9
import os
 
10
import subprocess
 
11
 
 
12
import gpodder
 
13
 
 
14
from gpodder import util
 
15
from gpodder import youtube
 
16
 
 
17
import logging
 
18
logger = logging.getLogger(__name__)
 
19
 
 
20
_ = gpodder.gettext
 
21
 
 
22
__title__ = _('Convert video files')
 
23
__description__ = _('Transcode video files to avi/mp4/m4v')
 
24
__authors__ = 'Thomas Perl <thp@gpodder.org>, Bernd Schlapsi <brot@gmx.info>'
 
25
__category__ = 'post-download'
 
26
 
 
27
DefaultConfig = {
 
28
    'output_format': 'mp4', # At the moment we support/test only mp4, m4v and avi
 
29
    'context_menu': True, # Show the conversion option in the context menu
 
30
}
 
31
 
 
32
 
 
33
class gPodderExtension:
 
34
    MIME_TYPES = ('video/mp4', 'video/m4v', 'video/x-flv', )
 
35
    EXT = ('.mp4', '.m4v', '.flv', )
 
36
    CMD = {'avconv': ['-i', '%(old_file)s', '-codec', 'copy', '%(new_file)s'],
 
37
           'ffmpeg': ['-i', '%(old_file)s', '-codec', 'copy', '%(new_file)s']
 
38
          }
 
39
 
 
40
    def __init__(self, container):
 
41
        self.container = container
 
42
        self.config = self.container.config
 
43
 
 
44
        # Dependency checks
 
45
        self.command = self.container.require_any_command(['avconv', 'ffmpeg'])
 
46
 
 
47
        # extract command without extension (.exe on Windows) from command-string
 
48
        command_without_ext = os.path.basename(os.path.splitext(self.command)[0])
 
49
        self.command_param = self.CMD[command_without_ext]
 
50
 
 
51
    def on_episode_downloaded(self, episode):
 
52
        self._convert_episode(episode)
 
53
        
 
54
    def _get_new_extension(self):
 
55
        ext = self.config.output_format
 
56
        if not ext.startswith('.'):
 
57
            ext = '.' + ext
 
58
 
 
59
        return ext
 
60
 
 
61
    def _check_source(self, episode):
 
62
        if episode.extension() == self._get_new_extension():
 
63
            return False
 
64
        
 
65
        if episode.mime_type in self.MIME_TYPES:
 
66
            return True
 
67
 
 
68
        # Also check file extension (bug 1770)
 
69
        if episode.extension() in self.EXT:
 
70
            return True
 
71
            
 
72
        return False
 
73
 
 
74
    def on_episodes_context_menu(self, episodes):
 
75
        if not self.config.context_menu:
 
76
            return None
 
77
 
 
78
        if not all(e.was_downloaded(and_exists=True) for e in episodes):
 
79
            return None
 
80
 
 
81
        if not any(self._check_source(episode) for episode in episodes):
 
82
            return None
 
83
 
 
84
        menu_item = _('Convert to %(format)s') % {'format': self.config.output_format}
 
85
 
 
86
        return [(menu_item, self._convert_episodes)]
 
87
 
 
88
    def _convert_episode(self, episode):
 
89
        if not self._check_source(episode):
 
90
            return
 
91
 
 
92
        new_extension = self._get_new_extension()
 
93
        old_filename = episode.local_filename(create=False)
 
94
        filename, old_extension = os.path.splitext(old_filename)
 
95
        new_filename = filename + new_extension
 
96
        
 
97
        cmd = [self.command] + \
 
98
            [param % {'old_file': old_filename, 'new_file': new_filename}
 
99
                for param in self.command_param]
 
100
        ffmpeg = subprocess.Popen(cmd, stdout=subprocess.PIPE,
 
101
                stderr=subprocess.PIPE)
 
102
        stdout, stderr = ffmpeg.communicate()
 
103
 
 
104
        if ffmpeg.returncode == 0:            
 
105
            util.rename_episode_file(episode, new_filename)
 
106
            os.remove(old_filename)
 
107
            
 
108
            logger.info('Converted video file to %(format)s.' % {'format': self.config.output_format})
 
109
            gpodder.user_extensions.on_notification_show(_('File converted'), episode.title)
 
110
        else:
 
111
            logger.warn('Error converting video file: %s / %s', stdout, stderr)
 
112
            gpodder.user_extensions.on_notification_show(_('Conversion failed'), episode.title)
 
113
 
 
114
    def _convert_episodes(self, episodes):
 
115
        for episode in episodes:
 
116
            self._convert_episode(episode)
 
117