Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add default codec properties #1450

Merged
merged 1 commit into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions av/container/output.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ class OutputContainer(Container):
def close(self) -> None: ...
def mux(self, packets: Packet | Sequence[Packet]) -> None: ...
def mux_one(self, packet: Packet) -> None: ...
@property
def default_video_codec(self) -> str: ...
@property
def default_audio_codec(self) -> str: ...
@property
def default_subtitle_codec(self) -> str: ...
23 changes: 23 additions & 0 deletions av/container/output.pyx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging
import os

cimport libav as lib

from av.codec.codec cimport Codec
from av.codec.context cimport CodecContext, wrap_codec_context
from av.container.streams cimport StreamContainer
Expand Down Expand Up @@ -192,6 +194,27 @@ cdef class OutputContainer(Container):

self._started = True

@property
def default_video_codec(self):
"""
Returns the default video codec this container recommends.
"""
return lib.avcodec_get_name(self.format.optr.video_codec)

@property
def default_audio_codec(self):
"""
Returns the default audio codec this container recommends.
"""
return lib.avcodec_get_name(self.format.optr.audio_codec)

@property
def default_subtitle_codec(self):
"""
Returns the default subtitle codec this container recommends.
"""
return lib.avcodec_get_name(self.format.optr.subtitle_codec)

def close(self):
for stream in self.streams:
if stream.codec_context:
Expand Down
4 changes: 4 additions & 0 deletions av/format.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
__all__ = ("ContainerFormat", "formats_available")

from typing import Literal

from .enum import EnumFlag

class Flags(EnumFlag):
Expand All @@ -22,10 +24,12 @@ class Flags(EnumFlag):
SEEK_TO_PTS: int

class ContainerFormat:
def __init__(self, name: str, mode: Literal["r", "w"] | None = None) -> None: ...
name: str
long_name: str
is_input: bool
is_output: bool
extensions: set[str]

# flags
no_file: int
Expand Down
26 changes: 21 additions & 5 deletions tests/test_containerformat.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
from av import ContainerFormat, formats_available
from av import ContainerFormat, formats_available, open

from .common import TestCase


class TestContainerFormats(TestCase):
def test_matroska(self):
def test_matroska(self) -> None:
with open("test.mkv", "w") as container:
self.assertNotEqual(container.default_video_codec, "none")
self.assertNotEqual(container.default_audio_codec, "none")
self.assertEqual(container.default_subtitle_codec, "ass")

fmt = ContainerFormat("matroska")
self.assertTrue(fmt.is_input)
self.assertTrue(fmt.is_output)
Expand All @@ -13,7 +18,12 @@ def test_matroska(self):
self.assertIn("mkv", fmt.extensions)
self.assertFalse(fmt.no_file)

def test_mov(self):
def test_mov(self) -> None:
with open("test.mov", "w") as container:
self.assertNotEqual(container.default_video_codec, "none")
self.assertNotEqual(container.default_audio_codec, "none")
self.assertEqual(container.default_subtitle_codec, "none")

fmt = ContainerFormat("mov")
self.assertTrue(fmt.is_input)
self.assertTrue(fmt.is_output)
Expand All @@ -22,7 +32,13 @@ def test_mov(self):
self.assertIn("mov", fmt.extensions)
self.assertFalse(fmt.no_file)

def test_stream_segment(self):
def test_gif(self) -> None:
with open("test.gif", "w") as container:
self.assertEqual(container.default_video_codec, "gif")
self.assertEqual(container.default_audio_codec, "none")
self.assertEqual(container.default_subtitle_codec, "none")

def test_stream_segment(self) -> None:
# This format goes by two names, check both.
fmt = ContainerFormat("stream_segment")
self.assertFalse(fmt.is_input)
Expand All @@ -40,5 +56,5 @@ def test_stream_segment(self):
self.assertEqual(fmt.extensions, set())
self.assertTrue(fmt.no_file)

def test_formats_available(self):
def test_formats_available(self) -> None:
self.assertTrue(formats_available)
Loading