Skip to content

Cannot set number of audio channels on output stream starting with PyAV version 13.0.0. #1627

@druzsan

Description

@druzsan

Overview

My goal is to write out an array of data as an audio file with the given sampling rate, format, codec and number of channels (mono, stereo, 5.1, 7.1 etc).

I am doing this in the following way (sampling rate, audio length, format and codec don't matter here):

import av
import av.audio
import numpy as np

sampling_rate = 44800
length = 5
num_channels = 6

data = np.random.random((num_channels, length * sampling_rate))

# "dblp" matches with float64 data types, "5.1" matches with (6, n) data size
frame = av.audio.AudioFrame.from_ndarray(data, "dblp", "5.1")
frame.rate = sampling_rate

with av.open("output.flac", "w", "flac") as container:
    stream = container.add_stream("flac", sampling_rate)
    stream.channels = num_channels
    container.mux(stream.encode(frame))
    container.mux(stream.encode(None))

Actual behavior

Up until version 12.3.0 this worked just as expected, but starting from the version 13.0.0 channels couldn't be set on a stream anymore.

Traceback:

Traceback (most recent call last):
  File "/home/alexander/dev/pyav/./test.py", line 23, in <module>
    stream.channels = num_channels
  File "av/stream.pyx", line 111, in av.stream.Stream.__setattr__
AttributeError: attribute 'channels' of 'av.audio.codeccontext.AudioCodecContext' objects is not writable

I tried stream = container.add_stream("flac", sampling_rate, channels=num_channels) instead of setting channels afterwards - works with version 12.3.0 but doesn't work with versions 13.0.0 and 13.1.0.

The other possibility would be to pass options to container.add_stream, but only the string values are allowed there.

If I leave it as is without setting channels on the stream, I always get stereo audio regardless of my data format.

Is there another way to set channels on an output stream?

Versions

  • OS: Ubuntu 24.04
  • Python: 3.10, also tested on 3.8, 3.9 and 3.11
  • PyAV runtime (13.0.0):
PyAV v13.0.0
library configuration: --disable-static --enable-shared --libdir=/tmp/vendor/lib --prefix=/tmp/vendor --disable-alsa --disable-doc --disable-libtheora --disable-libfreetype --disable-libfontconfig --disable-libbluray --disable-libopenjpeg --disable-mediafoundation --enable-gmp --enable-gnutls --enable-libaom --enable-libdav1d --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libspeex --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxcb --enable-libxml2 --enable-lzma --enable-zlib --enable-version3 --enable-libopenh264 --disable-libx264
library license: LGPL version 3 or later
libavcodec     61.  3.100
libavdevice    61.  1.100
libavfilter    10.  1.100
libavformat    61.  1.100
libavutil      59.  8.100
libswresample   5.  1.100
libswscale      8.  1.100
  • PyAV runtime (13.1.0):
PyAV v13.1.0
library configuration: --disable-static --enable-shared --libdir=/tmp/vendor/lib --prefix=/tmp/vendor --disable-alsa --disable-doc --disable-libtheora --disable-libfreetype --disable-libfontconfig --disable-libbluray --disable-libopenjpeg --disable-mediafoundation --enable-gmp --enable-gnutls --enable-libaom --enable-libdav1d --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libspeex --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxcb --enable-libxml2 --enable-lzma --enable-zlib --enable-version3 --enable-libopenh264 --disable-libx264
library license: LGPL version 3 or later
libavcodec     61. 19.100
libavdevice    61.  3.100
libavfilter    10.  4.100
libavformat    61.  7.100
libavutil      59. 39.100
libswresample   5.  3.100
libswscale      8.  3.100

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions