Skip to content

Commit 633f237

Browse files
committed
Copy template flags if creating a new Codec object
This fixes #1903
1 parent efe9ce2 commit 633f237

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

av/container/output.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ def add_stream(self, codec_name, rate=None, options: dict | None = None, **kwarg
130130

131131
return py_stream
132132

133-
def add_stream_from_template(self, template: Stream, opaque=None, **kwargs):
133+
def add_stream_from_template(
134+
self, template: Stream, opaque: bool | None = None, **kwargs
135+
):
134136
"""
135137
Creates a new stream from a template. Supports video, audio, and subtitle streams.
136138
@@ -170,6 +172,11 @@ def add_stream_from_template(self, template: Stream, opaque=None, **kwargs):
170172
if self.ptr.oformat.flags & lib.AVFMT_GLOBALHEADER:
171173
ctx.flags |= lib.AV_CODEC_FLAG_GLOBAL_HEADER
172174

175+
# Copy flags If we're creating a new codec object. This fixes some muxing issues.
176+
# Overwriting `ctx.flags |= lib.AV_CODEC_FLAG_GLOBAL_HEADER` is intentional.
177+
if not opaque:
178+
ctx.flags = template.codec_context.flags
179+
173180
# Initialize stream codec parameters to populate the codec type. Subsequent changes to
174181
# the codec context will be applied just before encoding starts in `start_encoding()`.
175182
err_check(lib.avcodec_parameters_from_context(stream.codecpar, ctx))

tests/test_remux.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import av
2+
import av.datasets
3+
4+
5+
def test_video_remux() -> None:
6+
input_path = av.datasets.curated("pexels/time-lapse-video-of-night-sky-857195.mp4")
7+
input_ = av.open(input_path)
8+
output = av.open("remuxed.mkv", "w")
9+
10+
in_stream = input_.streams.video[0]
11+
out_stream = output.add_stream_from_template(in_stream)
12+
13+
for packet in input_.demux(in_stream):
14+
if packet.dts is None:
15+
continue
16+
17+
packet.stream = out_stream
18+
output.mux(packet)
19+
20+
input_.close()
21+
output.close()
22+
23+
with av.open("remuxed.mkv") as container:
24+
# Assert output is a valid media file
25+
assert len(container.streams.video) == 1
26+
assert len(container.streams.audio) == 0
27+
assert container.streams.video[0].codec.name == "h264"
28+
29+
packet_count = 0
30+
for packet in container.demux(video=0):
31+
packet_count += 1
32+
33+
assert packet_count > 50

0 commit comments

Comments
 (0)