示例#1
0
 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)
示例#2
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')])
示例#3
0
 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')])
示例#4
0
    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'
        ])
示例#5
0
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
示例#6
0
    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)
示例#7
0
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)