src/pyams_media/converter.py
changeset 5 73e9b218db71
parent 0 fd39db613f8b
child 20 30a34a5cb19c
equal deleted inserted replaced
4:36c3db8c50a4 5:73e9b218db71
    18 
    18 
    19 from io import StringIO
    19 from io import StringIO
    20 from tempfile import NamedTemporaryFile
    20 from tempfile import NamedTemporaryFile
    21 
    21 
    22 # import interfaces
    22 # import interfaces
    23 from pyams_media.interfaces import IMediaVideoConverter, IMediaAudioConverter, IMediaConversionUtility, IMediaConverter
    23 from pyams_media.interfaces import IMediaVideoConverter, IMediaAudioConverter, IMediaConversionUtility, IMediaConverter, \
       
    24     VIDEO_FRAME_SIZE
    24 
    25 
    25 # import packages
    26 # import packages
    26 from pyams_media.ffdocument import FFDocument
    27 from pyams_media.ffdocument import FFDocument
    27 from pyams_utils.list import unique
    28 from pyams_utils.list import unique
    28 from pyams_utils.registry import utility_config, get_utilities_for, query_utility
    29 from pyams_utils.registry import utility_config, get_utilities_for, query_utility
    54             document = FFDocument(input.name)
    55             document = FFDocument(input.name)
    55         else:
    56         else:
    56             if isinstance(media, str):
    57             if isinstance(media, str):
    57                 media = StringIO(media)
    58                 media = StringIO(media)
    58             document = FFDocument(media)
    59             document = FFDocument(media)
    59         self.add_filters(document)
    60         self.add_common_filters(document)
    60         for loop in self.get_conversion_loop(document):
    61         for loop in self.get_conversion_loop(document):
    61             if self.require_temp_file:
    62             if self.require_temp_file:
    62                 output = NamedTemporaryFile(prefix='media_', suffix='.%s' % self.format)
    63                 output = NamedTemporaryFile(prefix='media_', suffix='.%s' % self.format)
    63                 document.get_output(self.format, target=output.name)
    64                 document.get_output(self.format, target=output.name)
    64                 output.file.seek(0)
    65                 output.file.seek(0)
    65                 yield loop, output.file.read()
    66                 yield loop, output.file.read()
    66             else:
    67             else:
    67                 yield loop, document.get_output(self.format)
    68                 yield loop, document.get_output(self.format)
    68 
    69 
       
    70     def add_common_filters(self, document):
       
    71         pass
       
    72 
    69     def add_filters(self, document):
    73     def add_filters(self, document):
    70         pass
    74         pass
    71 
    75 
    72     def get_conversion_loop(self, document):
    76     def get_conversion_loop(self, document):
       
    77         self.add_filters(document)
    73         yield None
    78         yield None
    74 
    79 
    75 
    80 
    76 #
    81 #
    77 # Audio converters
    82 # Audio converters
    78 #
    83 #
    79 
    84 
    80 @implementer(IMediaAudioConverter)
    85 @implementer(IMediaAudioConverter)
    81 class BaseAudioConverter(BaseMediaConverter):
    86 class BaseAudioConverter(BaseMediaConverter):
    82     """Base media converter"""
    87     """Base media converter"""
       
    88 
       
    89     def add_common_filters(self, document):
       
    90         super(BaseAudioConverter, self).add_common_filters(document)
       
    91         utility = query_utility(IMediaConversionUtility)
       
    92         if utility is not None:
       
    93             if utility.audio_sampling:
       
    94                 document.audiosampling(utility.audio_sampling)
       
    95             if utility.audio_bitrate:
       
    96                 document.audiobitrate(utility.audio_bitrate)
    83 
    97 
    84 
    98 
    85 @utility_config(name='audio/wav', provides=IMediaConverter)
    99 @utility_config(name='audio/wav', provides=IMediaConverter)
    86 class WavAudioConverter(BaseAudioConverter):
   100 class WavAudioConverter(BaseAudioConverter):
    87     """Default WAV media converter"""
   101     """Default WAV media converter"""
   137                 document.quantizerscale(utility.video_quantisation)
   151                 document.quantizerscale(utility.video_quantisation)
   138 
   152 
   139     def get_conversion_loop(self, document):
   153     def get_conversion_loop(self, document):
   140         utility = query_utility(IMediaConversionUtility)
   154         utility = query_utility(IMediaConversionUtility)
   141         if utility is not None:
   155         if utility is not None:
       
   156             # Get video resolution
       
   157             video_info = document.get_stream_info('video')
       
   158             if video_info is not None:
       
   159                 frame_width = video_info.get('width')
       
   160             else:
       
   161                 frame_width = (0, 0)
       
   162             # Check same resolution conversion
       
   163             if video_info.get('format', {}).get('format_name') != self.format:
       
   164                 yield None
       
   165             # Convert to lower resolutions
       
   166             self.add_filters(document)
   142             for size in utility.video_frame_size or ():
   167             for size in utility.video_frame_size or ():
   143                 document.size(size)
   168                 target_width = VIDEO_FRAME_SIZE.get(size, (0, 0))[0]
   144                 yield size
   169                 if target_width < frame_width:
       
   170                     document.size(size)
       
   171                     yield size
   145 
   172 
   146 
   173 
   147 @utility_config(name='video/x-flv', provides=IMediaConverter)
   174 @utility_config(name='video/x-flv', provides=IMediaConverter)
   148 class FlvVideoConverter(BaseVideoConverter):
   175 class FlvVideoConverter(BaseVideoConverter):
   149     """Default FLV media converter"""
   176     """Default FLV media converter"""
   150 
   177 
   151     label = _("FLV (Flash Video) video converter")
   178     label = _("FLV (Flash Video) video converter")
   152     format = 'flv'
   179     format = 'flv'
   153 
   180 
       
   181     def add_common_filters(self, document):
       
   182         super(FlvVideoConverter, self).add_common_filters(document)
       
   183         # Audio sampling is required by FLV converter!
       
   184         utility = query_utility(IMediaConversionUtility)
       
   185         if utility is not None:
       
   186             if utility.video_audio_sampling:
       
   187                 document.audiosampling(utility.video_audio_sampling)
       
   188 
   154 
   189 
   155 @utility_config(name='video/mp4', provides=IMediaConverter)
   190 @utility_config(name='video/mp4', provides=IMediaConverter)
   156 class Mp4VideoConverter(BaseVideoConverter):
   191 class Mp4VideoConverter(BaseVideoConverter):
   157     """Default MP4 media converter"""
   192     """Default MP4 media converter"""
   158 
   193 
   159     label = _("MP4 (HTML5) video converter")
   194     label = _("MP4 (HTML5) video converter")
   160     format = 'mp4'
   195     format = 'mp4'
   161     require_temp_file = True
   196     require_temp_file = True
   162 
   197 
       
   198     def add_common_filters(self, document):
       
   199         effects = document.__effects__
       
   200         effects['filter:v'] = 'setsar=1/1'
       
   201         effects['pix_fmt'] = 'yuv420p'
       
   202         effects['preset:v'] = 'slow'
       
   203         effects['profile:v'] = 'baseline'
       
   204         effects['x264opts'] = 'level=3.0:ref=1'
       
   205         effects['r:v'] = '25/1'
       
   206         effects['movflags'] = '+faststart'
       
   207 
   163 
   208 
   164 @utility_config(name='video/ogg', provides=IMediaConverter)
   209 @utility_config(name='video/ogg', provides=IMediaConverter)
   165 class OggVideoConverter(BaseVideoConverter):
   210 class OggVideoConverter(BaseVideoConverter):
   166     """OGG media converter"""
   211     """OGG media converter"""
   167 
   212 
   173 class WebmVideoConverter(BaseVideoConverter):
   218 class WebmVideoConverter(BaseVideoConverter):
   174     """WebM Media converter"""
   219     """WebM Media converter"""
   175 
   220 
   176     label = _("WebM video converter")
   221     label = _("WebM video converter")
   177     format = 'webm'
   222     format = 'webm'
       
   223 
       
   224     def add_common_filters(self, document):
       
   225         effects = document.__effects__
       
   226         effects['filter:v'] = 'setsar=1/1'
       
   227         effects['pix_fmt'] = 'yuv420p'
       
   228         effects['r:v'] = '25/1'
   178 
   229 
   179 
   230 
   180 class VideoConvertersVocabulary(SimpleVocabulary):
   231 class VideoConvertersVocabulary(SimpleVocabulary):
   181     """Video converters vocabulary"""
   232     """Video converters vocabulary"""
   182 
   233