def test_pipe(self): self.false(Media(None).is_pipe) self.false(Media('test-file.mp4').is_pipe) for path in '-', 'pipe:3': media = Media(path) self.is_none(media.directory) self.true(media.is_pipe) self.equal(media.size, 0)
def test_clean_medias_argument(self): eq = self.assertListEqual clean = self.ffmpeg._clean_medias_argument eq(clean(None), []) eq(clean([]), []) eq(clean('a.mp4'), [Media('a.mp4')]) eq(clean(['a.mp4', 'b.mp3']), [Media('a.mp4'), Media('b.mp3')]) eq(clean(Media('a', '-f mp4')), [Media('a', ['-f', 'mp4'])]) eq(clean([Media('a', ['-f', 'mp4']), Media('b.mp3')]), [Media('a', ['-f', 'mp4']), Media('b.mp3')])
def test_clean_medias_argument(self): clean = self.ffmpeg._clean_medias_argument self.list_equal(clean(None), []) self.list_equal(clean([]), []) self.list_equal(clean('a.mp4'), [Media('a.mp4')]) self.list_equal(clean(['a.mp4', 'b.mp3']), [Media('a.mp4'), Media('b.mp3')]) self.list_equal(clean(Media('a', '-f mp4')), [Media('a', ['-f', 'mp4'])]) self.list_equal(clean([Media('a', ['-f', 'mp4']), Media('b.mp3')]), [Media('a', ['-f', 'mp4']), Media('b.mp3')])
def test_get_arguments(self): eq = self.assertListEqual get = self.ffmpeg._get_arguments self.ffmpeg.executable = 'ffmpeg' # Using options (the legacy API, also simplify simple calls) options_string = '-strict experimental -vf "yadif=0.-1:0, scale=trunc(iw/2)*2:trunc(ih/2)*2"' args, inputs, outputs, options = get('input.mp4', 'output.mkv', options_string) eq(inputs, [Media('input.mp4')]) eq(outputs, [Media('output.mkv')]) eq(options, [ '-strict', 'experimental', '-vf', 'yadif=0.-1:0, scale=trunc(iw/2)*2:trunc(ih/2)*2' ]) eq(args, ['ffmpeg', '-y', '-i', 'input.mp4'] + options + ['output.mkv']) args, _, outputs, options = get('input.mp4', None, options_string) eq(outputs, []) eq(args, ['ffmpeg', '-y', '-i', 'input.mp4'] + options) # Using instances of Media (the newest API, greater flexibility) args, inputs, outputs, options = get( Media('in', '-f mp4'), Media('out.mkv', '-acodec copy -vcodec copy')) eq(inputs, [Media('in', ['-f', 'mp4'])]) eq(outputs, [Media('out.mkv', ['-acodec', 'copy', '-vcodec', 'copy'])]) eq(options, []) eq(args, [ 'ffmpeg', '-y', '-f', 'mp4', '-i', 'in', '-acodec', 'copy', '-vcodec', 'copy', 'out.mkv' ])
class _EncodeStatisticsMixin(object): inputs = [Media('small.mp4')] outputs = [Media('ff_output.mp4')] statistics_class = StaticEncodeStatistics def get_statistics(self, start=False, returncode=None, options=None, **kwargs): if options is None: options = ['-acodec', 'copy', '-vcodec', 'copy'] statistics = self.statistics_class(self.inputs, self.outputs, options, **kwargs) start = start or returncode is not None if start: statistics.start('process') if returncode is not None: statistics.progress('') statistics.end(returncode) return statistics
def test_encode(self): results = list( self.ffmpeg.encode(Media('small.mp4'), Media('ff_output.mp4', '-c:a copy -c:v copy'))) self.true(remove('ff_output.mp4')) self.equal(results[-1].state, EncodeState.SUCCESS) results = list( self.ffmpeg.encode(Media('small.mp4'), Media('ff_output.mp4', 'crazy_option'))) self.false(remove('ff_output.mp4')) self.equal(results[-1].state, EncodeState.FAILURE) results = list( self.ffmpeg.encode([Media('missing.mp4')], Media('ff_output.mp4', '-c:a copy -c:v copy'))) self.false(remove('ff_output.mp4')) self.equal(results[-1].state, EncodeState.FAILURE)
class TestEncodeStatistics(FilterByTagsMixin, unittest.TestCase): tags = ('multimedia', 'ffmpeg') inputs = [Media('small.mp4')] outputs = [Media('ff_output.mp4')] def get_statistics(self, start=False, returncode=None, options=['-acodec', 'copy', '-vcodec', 'copy'], **kwargs): statistics = EncodeStatistics(self.inputs, self.outputs, options, **kwargs) start = start or returncode is not None if start: statistics.start('process') if returncode is not None: statistics.progress('') statistics.end(returncode) return statistics def test_get_subclip_duration_and_size(self): eq, subclip = self.assertTupleEqual, self.get_statistics( )._get_subclip_duration_and_size duration = datetime.timedelta(hours=1, minutes=30, seconds=36.5) sub_dur_1 = datetime.timedelta(seconds=3610.2) sub_dur_2 = datetime.timedelta(hours=1, minutes=20, seconds=15.8) sub_dur_3 = datetime.timedelta(minutes=40, seconds=36.3) sub_dur_4 = datetime.timedelta(0) eq(subclip(duration, 512 * 1024, []), (duration, 512 * 1024)) eq(subclip(duration, 512 * 1024, ['-t']), (duration, 512 * 1024)) eq(subclip(duration, 512 * 1024, ['-t', '-t']), (duration, 512 * 1024)) eq(subclip(duration, 512 * 1024, ['-t', '3610.2']), (sub_dur_1, 348162)) eq(subclip(duration, 512 * 1024, ['-t', '01:20:15.8']), (sub_dur_2, 464428)) eq( subclip(duration, 512 * 1024, ['-t', '01:20:15.8', '-ss', '00:50:00.2']), (sub_dur_3, 234953)) eq( subclip(duration, 512 * 1024, ['-t', '01:20:15.8', '-ss', '01:30:36.5']), (sub_dur_4, 0)) eq(subclip(duration, 512 * 1024, ['-ss', '01:30:53']), (sub_dur_4, 0)) eq(subclip(duration, 512 * 1024, ['-t', '02:00:00.0']), (duration, 512 * 1024)) def test_parse_chunk(self): statistics = self.get_statistics() eq, parse = self.assertDictEqual, statistics._parse_chunk self.assertIsNone(parse('Random stuff')) eq( parse( ' frame= 2071 fps= 0 q=-1.0 size= 34623kB time=00:01:25.89 bitrate=3302.3kbits/s ' ), { 'frame': 2071, 'fps': 0.0, 'q': -1.0, 'size': 34623 * 1024, 'time': datetime.timedelta(minutes=1, seconds=25.89), 'bitrate': 3302300 }) def test_should_report_initialization(self): statistics = self.get_statistics() self.assertTrue(statistics._should_report()) self.assertEqual(statistics._prev_elapsed_time, datetime.timedelta(0)) self.assertEqual(statistics._prev_ratio, 0) self.assertFalse(statistics._should_report()) def test_should_report_elapsed_time_criteria(self): statistics = self.get_statistics() self.assertTrue(statistics._should_report()) statistics.elapsed_time = datetime.timedelta(seconds=3) self.assertFalse(statistics._should_report()) statistics.elapsed_time = datetime.timedelta(seconds=6) self.assertTrue(statistics._should_report()) self.assertFalse(statistics._should_report()) def test_should_report_ratio_criteria(self): statistics = self.get_statistics() self.assertTrue(statistics._should_report()) statistics.ratio = 0.001 self.assertFalse(statistics._should_report()) statistics.ratio = 0.02 self.assertFalse(statistics._should_report()) statistics.elapsed_time = datetime.timedelta(seconds=2) self.assertTrue(statistics._should_report()) self.assertFalse(statistics._should_report()) def test_eta_time(self): statistics = self.get_statistics() statistics.elapsed_time = datetime.timedelta(seconds=60) self.assertIsNone(statistics.eta_time) statistics.ratio = 0.0 self.assertIsNone(statistics.eta_time) statistics.ratio = 0.2 self.assertEqual(statistics.eta_time, datetime.timedelta(seconds=240)) statistics.ratio = 0.5 self.assertEqual(statistics.eta_time, datetime.timedelta(seconds=60)) statistics.ratio = 1.0 self.assertEqual(statistics.eta_time, datetime.timedelta(0)) def test_compute_ratio(self): statistics = self.get_statistics() statistics.input.duration = datetime.timedelta(seconds=0) statistics.output.duration = None self.assertIsNone(statistics._compute_ratio()) statistics.input.duration = datetime.timedelta(seconds=0) statistics.output.duration = datetime.timedelta(0) self.assertIsNone(statistics._compute_ratio()) statistics.input.duration = datetime.timedelta(seconds=1) self.assertEqual(statistics._compute_ratio(), 0.0) statistics.input.duration = datetime.timedelta(seconds=60) statistics.output.duration = datetime.timedelta(seconds=30) self.assertEqual(statistics._compute_ratio(), 0.5) def test_new_properties(self): statistics = self.get_statistics() self.assertIsInstance(statistics.input.duration, datetime.timedelta) self.assertIsNone(statistics.eta_time) self.assertEqual(statistics.input, statistics.inputs[0]) self.assertEqual(statistics.output, statistics.outputs[0]) self.assertIsNone(statistics.ratio) self.assertIsNotNone(statistics.input._size) def test_started_properties(self): statistics = self.get_statistics(start=True) self.assertEqual(statistics.output.duration, datetime.timedelta(0)) self.assertIsNone(statistics.eta_time) self.assertEqual(statistics.ratio, 0.0) def test_success_properties(self): self.outputs[0].filename = self.inputs[0].filename statistics = self.get_statistics(returncode=0) self.assertEqual(statistics.output.duration, statistics.input.duration) self.assertEqual(statistics.eta_time, datetime.timedelta(0)) self.assertEqual(statistics.ratio, 1.0) self.assertIsNone(statistics.output._size)