Add video stream copy remuxing
This commit is contained in:
@@ -31,6 +31,7 @@ from tools.video_timestamp_encode import write_timecode_v2, x264_command
|
||||
from tools.video_encode_plan import (
|
||||
missing_source_frames_between_kept,
|
||||
normal_deleted_frame_count,
|
||||
preserves_entire_source_timeline,
|
||||
y4m_command_for_timeline,
|
||||
)
|
||||
from tools.video_codec_constraints import (
|
||||
@@ -46,11 +47,14 @@ from tools.video_inputs import VideoInput
|
||||
from tools.video_options import OutputNamingOptions
|
||||
from tools.video_outputs import output_begin_timestamp, planned_output_path
|
||||
from tools.video_batch_encode import (
|
||||
EncodingOutputSpec,
|
||||
_default_output_timezone,
|
||||
_default_answer,
|
||||
_encoding_steps,
|
||||
_parse_audio,
|
||||
_parse_answer,
|
||||
_question_for_key,
|
||||
_stream_copy_warnings,
|
||||
)
|
||||
from tools.video_probe import AudioStreamProbe, VideoProbe, _video_timezone, summarize_frame_timing
|
||||
from tools.video_reporting import _format_probe_timestamp, _format_vfr_timing
|
||||
@@ -109,6 +113,89 @@ def make_probe(
|
||||
|
||||
|
||||
class VideoCodecConstraintTests(unittest.TestCase):
|
||||
def test_video_copy_is_only_available_for_a_full_source_timeline(self) -> None:
|
||||
source = OutputTimeline(
|
||||
frames=[OutputFrameTiming(index, 1, index, float(index), 1.0) for index in range(3)],
|
||||
audio_segments=[(0.0, 3.0)],
|
||||
consumed_source_frames=[0, 1, 2],
|
||||
duration_seconds=3.0,
|
||||
timing_kind="cfr",
|
||||
beginning_trimmed=False,
|
||||
ending_trimmed=False,
|
||||
dropped_frame_count=0,
|
||||
source_frame_count=3,
|
||||
matrix=None,
|
||||
)
|
||||
trimmed = OutputTimeline(
|
||||
frames=source.frames[:2],
|
||||
audio_segments=[(0.0, 2.0)],
|
||||
consumed_source_frames=[0, 1],
|
||||
duration_seconds=2.0,
|
||||
timing_kind="cfr",
|
||||
beginning_trimmed=False,
|
||||
ending_trimmed=True,
|
||||
dropped_frame_count=0,
|
||||
source_frame_count=3,
|
||||
matrix=None,
|
||||
)
|
||||
|
||||
self.assertTrue(preserves_entire_source_timeline(source))
|
||||
self.assertFalse(preserves_entire_source_timeline(trimmed))
|
||||
|
||||
def test_mp4_stream_copy_warnings_name_incompatible_streams(self) -> None:
|
||||
specs = [
|
||||
EncodingOutputSpec(
|
||||
label="clip.mkv",
|
||||
width=1920,
|
||||
height=1080,
|
||||
bit_depth=8,
|
||||
chroma="420",
|
||||
fps=30.0,
|
||||
begin_utc="unknown",
|
||||
summary_lines=(),
|
||||
video_codec="prores",
|
||||
audio_codecs=("pcm_s16le",),
|
||||
)
|
||||
]
|
||||
|
||||
warnings = _stream_copy_warnings(
|
||||
extension=".mp4",
|
||||
video_codec="copy",
|
||||
audio_mode="copy",
|
||||
specs=specs,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
warnings,
|
||||
["does not support prores video", "does not support pcm_s16le audio"],
|
||||
)
|
||||
|
||||
def test_mp4_allows_opus_and_flac_audio(self) -> None:
|
||||
self.assertEqual(_parse_audio("opus"), "opus")
|
||||
self.assertEqual(_parse_audio("flac"), "flac")
|
||||
spec = EncodingOutputSpec(
|
||||
label="clip.mp4",
|
||||
width=1920,
|
||||
height=1080,
|
||||
bit_depth=8,
|
||||
chroma="420",
|
||||
fps=30.0,
|
||||
begin_utc="unknown",
|
||||
summary_lines=(),
|
||||
video_codec="h264",
|
||||
audio_codecs=("flac",),
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
_stream_copy_warnings(
|
||||
extension=".mp4",
|
||||
video_codec="libx265",
|
||||
audio_mode="copy",
|
||||
specs=[spec],
|
||||
),
|
||||
[],
|
||||
)
|
||||
|
||||
def test_pixel_format_preserves_ten_bit_output(self) -> None:
|
||||
formats = [
|
||||
(8, "yuv420p"),
|
||||
|
||||
Reference in New Issue
Block a user