PyAV-Org / PyAV

Pythonic bindings for FFmpeg's libraries.
https://pyav.basswood-io.com/
BSD 3-Clause "New" or "Revised" License
2.44k stars 359 forks source link

How do I write to webp? #1352

Closed FredHappyface closed 3 months ago

FredHappyface commented 5 months ago

Thanks for the awesome project, I was kindly informed about this when investigating performance when converting tgs/lottie using python-rlottie + pillow

Overview

I've been able to use pyav to write to 'gif' and 'apng' sucessfully, however, I cannot work out if webp is supported, the errors suggest not but I just wanted to clarify as I'm pretty new to using this library

from typing import cast 

import av
import numpy as np
from av.video.stream import VideoStream
from rlottie_python import LottieAnimation

anim = LottieAnimation.from_tgs("sample.tgs")

frames = anim.lottie_animation_get_totalframe()
fps = anim.lottie_animation_get_framerate()
width, height = anim.lottie_animation_get_size()
options = {
    "loop": "0"
}

with av.open(f"sample.webp", "w", format="webp") as output:
    out_stream = output.add_stream("webp", rate=fps, options=options)
    out_stream = cast(VideoStream, out_stream)
    out_stream.width = width
    out_stream.height = height
    out_stream.pix_fmt = "rgb8"

    for i in range(frames):
        buffer = anim.lottie_animation_render(i)
        frame = np.frombuffer(buffer, dtype=np.uint8).reshape((width, height, 4))
        av_frame = av.VideoFrame.from_ndarray(frame, format="bgra")
        output.mux(out_stream.encode(av_frame))
    output.mux(out_stream.encode())

anim.lottie_animation_destroy()

Expected behavior

A list of supported codecs somewhere would be really useful as I've not been able to find these

Actual behavior

'webp' codec is not available, same behaviour when using 'libwebp'

Traceback:

    out_stream = output.add_stream("webp", rate=fps, options=options)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "av\\container\\output.pyx", line 67, in av.container.output.OutputContainer.add_stream  
  File "av\\codec\\codec.pyx", line 185, in av.codec.codec.Codec.__cinit__
  File "av\\codec\\codec.pyx", line 194, in av.codec.codec.Codec._init
av.codec.codec.UnknownCodecError: webp

Investigation

Tried searching the docs for supported codecs, tried looking through the code and searching the repo for 'gif' 'webp' etc and have found no results. Searching webp and ffmpeg suggests it is supported

Research

I have done the following:

Additional context

{{ Add any other context about the problem here. }}

WyattBlue commented 5 months ago

Right now, we don't currently build wheels with webp support.

laggykiller commented 3 months ago

@WyattBlue Why not though? I have successfully built ffmpeg with libwebp then build pyav with libwebp-enabled ffmpeg without problem.

My fork of pyav-ffmpeg that can build libwebp-enabled ffmpeg: https://github.com/laggykiller/pyav-ffmpeg/tree/enable-libwebp

The built pyav wheels could be downloaded from here: https://github.com/laggykiller/PyAV/releases/tag/6.1.0-libwebp-1

I can open PR for this: https://github.com/PyAV-Org/pyav-ffmpeg/compare/main...laggykiller:pyav-ffmpeg:enable-libwebp

If you don't want to enable libwebp in pyav, I can just maintain my fork and upload to pypi.

WyattBlue commented 3 months ago

@laggykiller You should make a PR for https://github.com/PyAV-Org/pyav-ffmpeg

laggykiller commented 3 months ago

@WyattBlue Opened PR https://github.com/PyAV-Org/pyav-ffmpeg/pull/96

jlaine commented 3 months ago

I have merged @laggykiller, once CI completes I will point PyAV's build to the new binaries.