示例#1
0
 def test_replace_streams_command_validates_stream_type(self):
     with self.assertRaises(exceptions.InvalidArgument):
         commands.replace_streams_command(
             get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mp4'),
             get_absolute_resource_path(
                 'ForBiggerBlazes-[codec=h264][video-only].mkv'),
             get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mkv'),
             "v:1",
             {},
         )
示例#2
0
 def test_replace_streams_command_does_not_accept_video_parameters(self):
     with self.assertRaises(exceptions.InvalidArgument):
         commands.replace_streams_command(
             get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mp4'),
             get_absolute_resource_path(
                 'ForBiggerBlazes-[codec=h264][video-only].mkv'),
             get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mkv'),
             "v", {
                 'video': {
                     'codec': 'h264',
                     'bitrate': '1000k',
                 },
             })
    def test_generate_sample_video_command_should_support_multiple_streams_with_same_codec(
            self):
        output_path = os.path.join(self.tmp_dir, 'output.mp4')
        requested_streams_with_types = [
            ('subtitle', 'mov_text'),
            ('video', 'h264'),
            ('video', 'h264'),
            ('subtitle', 'mov_text'),
        ]
        requested_streams = [
            codec_name
            for codec_type, codec_name in requested_streams_with_types
        ]

        expected_command = [
            commands.FFMPEG_COMMAND,
            "-nostdin",
            "-i",
            get_absolute_resource_path('sample.srt'),
            "-i",
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mp4'),
            "-map",
            "0:0",
            "-codec:0",
            "mov_text",
            "-map",
            "1:0",
            "-codec:1",
            "h264",
            "-map",
            "1:0",
            "-codec:2",
            "h264",
            "-map",
            "0:0",
            "-codec:3",
            "mov_text",
            "-f",
            "mp4",
            output_path,
        ]

        command = generate_sample_video_command(
            requested_streams,
            output_path,
            container='mp4',
        )

        self.assertEqual(command, expected_command)
    def test_extract_split_transcoding_merge_replace(self):
        input_path = get_absolute_resource_path(
            "ForBiggerBlazes-[codec=h264].mp4")
        input_metadata = commands.get_metadata_json(input_path)
        validation.validate_video(input_metadata)

        transcode_step_targs = {
            'container': formats.Container.c_MATROSKA.value,
            'frame_rate': '25/1',
            'video': {
                'codec': codecs.VideoCodec.VP8.value,
                'bitrate': '1000k',
            },
            'resolution': [160, 90],
            'scaling_alg': 'neighbor',
        }
        replace_step_targs = {
            'audio': {
                'codec': codecs.AudioCodec.MP3.value,
                'bitrate': '128k',
            },
        }

        validation.validate_transcoding_params(
            {
                **transcode_step_targs,
                **replace_step_targs
            },
            input_metadata,
            commands.query_muxer_info(transcode_step_targs['container']),
            commands.query_encoder_info(codecs.VideoCodec.VP8.get_encoder()),
        )

        self.run_extract_split_transcoding_merge_replace_test(
            num_segments=3,
            input_path=input_path,
            extract_step_output_path=os.path.join(
                self.work_dirs['extract'],
                "ForBiggerBlazes-[codec=h264][video-only].mp4"),
            split_step_basename_template=
            "ForBiggerBlazes-[codec=h264][video-only]_{}.mp4",
            transcode_step_basename_template=
            "ForBiggerBlazes-[codec=h264][video-only]_{}_TC.mkv",
            merge_step_output_path=os.path.join(
                self.work_dirs['merge'],
                "ForBiggerBlazes-[codec=h264][video-only]_TC.mkv"),
            replace_step_output_path=os.path.join(
                self.work_dirs['replace'],
                "ForBiggerBlazes-[codec=h264]_TC.mkv"),
            ffconcat_list_path=os.path.join(self.work_dirs['transcode'],
                                            "merge-input.ffconcat"),
            transcode_step_targs=transcode_step_targs,
            replace_step_targs=replace_step_targs,
        )
    def test_replace_streams_converts_subtitles(self):
        input_path = os.path.join(self.tmp_dir, 'input.mkv')
        replacement_path = get_absolute_resource_path(
            "ForBiggerBlazes-[codec=h264].mp4")
        output_path = os.path.join(self.tmp_dir, 'output.mp4')
        generate_sample_video([
            codecs.SubtitleCodec.ASS.value,
            codecs.VideoCodec.MJPEG.value,
            codecs.AudioCodec.MP3.value,
            codecs.SubtitleCodec.SUBRIP.value,
            codecs.VideoCodec.FLV1.value,
            codecs.AudioCodec.AAC.value,
            codecs.SubtitleCodec.WEBVTT.value,
        ],
                              input_path,
                              container=formats.Container.c_MATROSKA.value)

        assert os.path.isfile(input_path)
        assert not os.path.isfile(output_path)

        commands.replace_streams(
            input_path,
            replacement_path,
            output_path,
            stream_type='v',
            targs={},
            container=formats.Container.c_MP4.value,
            strip_unsupported_data_streams=True,
            strip_unsupported_subtitle_streams=True,
        )

        self.assertTrue(os.path.isfile(output_path))

        metadata = meta.get_metadata(output_path)
        self.assertEqual(meta.get_format(metadata),
                         formats.Container.c_QUICK_TIME_DEMUXER.value)
        self.assertIn('streams', metadata)

        expected_streams = [
            ('video', codecs.VideoCodec.H_264.value),
            ('subtitle', codecs.SubtitleCodec.MOV_TEXT.value),
            ('audio', codecs.AudioCodec.AAC.value),
            ('subtitle', codecs.SubtitleCodec.MOV_TEXT.value),
            ('audio', codecs.AudioCodec.AAC.value),
            ('subtitle', codecs.SubtitleCodec.MOV_TEXT.value),
        ]
        streams = [(stream_metadata.get('codec_type'),
                    stream_metadata.get('codec_name'))
                   for stream_metadata in metadata['streams']]
        self.assertEqual(streams, expected_streams)
示例#6
0
    def test_transcoding(self):
        params = meta.create_params("mp4", [1280, 800], "h265")

        input_video = get_absolute_resource_path(
            'ForBiggerBlazes-[codec=h264].mp4')
        output_video = os.path.join(tempfile.gettempdir(),
                                    "ForBiggerBlazes-[codec=h265].mp4")

        if os.path.exists(output_video):
            os.remove(output_video)

        commands.transcode_video(input_video, params, output_video)

        assert os.path.exists(output_video)
示例#7
0
    def test_replace_streams_command_removes_streams_not_in_whitelist_if_asked_to(
        self,
        _mock_find_unsupported_subtitle_streams,
        _mock_find_unsupported_data_streams,
        _mock_get_metadata_json,
    ):
        command = commands.replace_streams_command(
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mp4'),
            get_absolute_resource_path(
                'ForBiggerBlazes-[codec=h264][video-only].mkv'),
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mkv'),
            "v", {},
            strip_unsupported_data_streams=True,
            strip_unsupported_subtitle_streams=True)

        expected_command = [
            "ffmpeg",
            "-nostdin",
            "-i",
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mp4'),
            "-i",
            get_absolute_resource_path(
                'ForBiggerBlazes-[codec=h264][video-only].mkv'),
            "-map",
            "1:v",
            "-map",
            "0",
            "-map",
            "-0:v",
            '-map',
            '-0:2',
            '-map',
            '-0:3',
            "-copy_unknown",
            "-c:v",
            "copy",
            "-c:d",
            "copy",
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mkv'),
        ]
        self.assertEqual(command, expected_command)
示例#8
0
    def test_replace_streams_command(self, _mock_get_metadata_json):
        command = commands.replace_streams_command(
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mp4'),
            get_absolute_resource_path(
                'ForBiggerBlazes-[codec=h264][video-only].mkv'),
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mkv'),
            "v",
            {'audio': {
                'codec': 'mp3',
                'bitrate': '128k',
            }},
        )

        expected_command = [
            "ffmpeg",
            "-nostdin",
            "-i",
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mp4'),
            "-i",
            get_absolute_resource_path(
                'ForBiggerBlazes-[codec=h264][video-only].mkv'),
            "-map",
            "1:v",
            "-map",
            "0",
            "-map",
            "-0:v",
            "-copy_unknown",
            "-c:v",
            "copy",
            "-c:d",
            "copy",
            "-c:a",
            codecs.AudioCodec.get_encoder(codecs.AudioCodec.MP3),
            "-b:a",
            "128k",
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mkv'),
        ]
        self.assertEqual(command, expected_command)
    def test_generate_sample_video_command(self):
        output_path = os.path.join(self.tmp_dir, 'output.mkv')
        requested_streams = [
            codec_name for codec_type, codec_name in self.ALMOST_ALL_STREAMS
        ]

        expected_command = [
            commands.FFMPEG_COMMAND,
            "-nostdin",
            "-i",
            get_absolute_resource_path('ForBiggerBlazes-[codec=h264].mp4'),
            "-i",
            get_absolute_resource_path('sample.srt'),
            "-map",
            "0:0",
            "-codec:0",
            "h264",
            "-map",
            "0:0",
            "-codec:1",
            "mjpeg",
            "-map",
            "0:0",
            "-codec:2",
            "flv1",
            "-map",
            "0:0",
            "-codec:3",
            "vp8",
            "-map",
            "0:1",
            "-codec:4",
            "aac",
            "-map",
            "0:1",
            "-codec:5",
            "mp3",
            "-map",
            "1:0",
            "-codec:6",
            "subrip",
            "-map",
            "1:0",
            "-codec:7",
            "ass",
            "-map",
            "1:0",
            "-codec:8",
            "webvtt",
            "-f",
            "matroska",
            output_path,
        ]

        command = generate_sample_video_command(
            requested_streams,
            output_path,
            container='matroska',
        )

        self.assertEqual(command, expected_command)
示例#10
0
    def test_get_video_length(self):
        input_video = get_absolute_resource_path(
            'ForBiggerBlazes-[codec=h264].mp4')
        length = commands.get_video_len(input_video)

        assert length == 15.021667