diff --git a/av/container/output.py b/av/container/output.py index 64a4f4a53..d035b0265 100644 --- a/av/container/output.py +++ b/av/container/output.py @@ -130,7 +130,9 @@ def add_stream(self, codec_name, rate=None, options: dict | None = None, **kwarg return py_stream - def add_stream_from_template(self, template: Stream, opaque=None, **kwargs): + def add_stream_from_template( + self, template: Stream, opaque: bool | None = None, **kwargs + ): """ Creates a new stream from a template. Supports video, audio, and subtitle streams. @@ -170,6 +172,11 @@ def add_stream_from_template(self, template: Stream, opaque=None, **kwargs): if self.ptr.oformat.flags & lib.AVFMT_GLOBALHEADER: ctx.flags |= lib.AV_CODEC_FLAG_GLOBAL_HEADER + # Copy flags If we're creating a new codec object. This fixes some muxing issues. + # Overwriting `ctx.flags |= lib.AV_CODEC_FLAG_GLOBAL_HEADER` is intentional. + if not opaque: + ctx.flags = template.codec_context.flags + # Initialize stream codec parameters to populate the codec type. Subsequent changes to # the codec context will be applied just before encoding starts in `start_encoding()`. err_check(lib.avcodec_parameters_from_context(stream.codecpar, ctx)) diff --git a/tests/test_remux.py b/tests/test_remux.py new file mode 100644 index 000000000..1eca2dfd2 --- /dev/null +++ b/tests/test_remux.py @@ -0,0 +1,33 @@ +import av +import av.datasets + + +def test_video_remux() -> None: + input_path = av.datasets.curated("pexels/time-lapse-video-of-night-sky-857195.mp4") + input_ = av.open(input_path) + output = av.open("remuxed.mkv", "w") + + in_stream = input_.streams.video[0] + out_stream = output.add_stream_from_template(in_stream) + + for packet in input_.demux(in_stream): + if packet.dts is None: + continue + + packet.stream = out_stream + output.mux(packet) + + input_.close() + output.close() + + with av.open("remuxed.mkv") as container: + # Assert output is a valid media file + assert len(container.streams.video) == 1 + assert len(container.streams.audio) == 0 + assert container.streams.video[0].codec.name == "h264" + + packet_count = 0 + for packet in container.demux(video=0): + packet_count += 1 + + assert packet_count > 50