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

About http://mikeboers.github.io/PyAV/examples.html #255

Closed
hhsprings opened this issue Jul 16, 2017 · 4 comments
Closed

About http://mikeboers.github.io/PyAV/examples.html #255

hhsprings opened this issue Jul 16, 2017 · 4 comments

Comments

@hhsprings
Copy link

The bellow snippet is almost the same as Examples:

# -*- coding: utf-8 -*-
import numpy as np
import av

duration = 10  # Seconds
frames_per_second = 24
total_frames = duration * frames_per_second

container = av.open('test.mp4', mode='w')

stream = container.add_stream('mpeg4', rate=frames_per_second)
stream.width = 480
stream.height = 320
stream.pix_fmt = 'yuv420p'

for frame_i in range(total_frames):
    img = np.empty((480, 320, 3))

    img[:, :, 0] = 0.5 + 0.5 * np.sin(frame_i / duration * 2 * np.pi)
    img[:, :, 1] = 0.5 + 0.5 * np.sin(frame_i / duration * 2 * np.pi + 2 / 3 * np.pi)
    img[:, :, 2] = 0.5 + 0.5 * np.sin(frame_i / duration * 2 * np.pi + 4 / 3 * np.pi)

    img = np.round(255 * img).astype(np.uint8)
    img[img < 0] = 0
    img[img > 255] = 255

    frame = av.VideoFrame.from_ndarray(img, format='rgb24')
    packet = stream.encode(frame)
    if packet is not None:
        container.mux(packet)

# Finish encoding the stream
#while True:                   # This causes End Of File error...
#    packet = stream.encode()  # (with ffmpeg 3.2.4, 3.3.2)
#    if packet is None:        #
#        break                 #
#    container.mux(packet)     #

# Close the file
container.close()

About this example, I have three questions.


  1. It seems that the codes explained as "Finish encoding the stream" causes End Of File error from av/utils.pyx:
Traceback (most recent call last):
  File "myexample.py", line 34, in <module>
    packet = stream.encode()
  File "av/stream.pyx", line 121, in av.stream.Stream.encode (src/av/stream.c:3391)
    packets = self.codec_context.encode(frame)
  File "av/codec/context.pyx", line 285, in av.codec.context.CodecContext.encode (src/av/codec/context.c:5694)
    for packet in self._send_frame_and_recv(frame):
  File "av/codec/context.pyx", line 198, in av.codec.context.CodecContext._send_frame_and_recv (src/av/codec/context.c:4585)
    err_check(lib.avcodec_send_frame(self.ptr, frame.ptr if frame else NULL))
  File "av/utils.pyx", line 105, in av.utils.err_check (src/av/utils.c:2571)
    raise AVError(-res, message, None,     error_log)
av.AVError: [Errno 541478725] End of file

Question: Must we do always "Finish encoding the stream"? If so, how do we write this? And what does it mean?


  1. With commenting out the "Finish encoding the stream", we can produce "test.mp4", but using with CPython 2.7, "test.mp4" is not what we want (not colored movie).

Question: According to classifiers, PyAV doesn't drop the support for Python 2.7, but actually seems not. What is the situation for supporting Python 2.x?


  1. Using with CPython 3.5 (and maybe with properly log configured CPython 2.7), this example causes
    the warning from AVStream:
Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.

(I tried this with ffmpeg 3.2.4 and 3.3.2, the both seems the same.)

Question: What version of ffmpeg should we use currently? At least, the build-deps seems to expect 3.2.

@hhsprings
Copy link
Author

Sorry, please ignore the third question. (I have not noticed #222.)

@mikeboers
Copy link
Member

Part 1: The example is very likely bad given recent changes to the API (in which encode and decode methods both always return lists (so it can never return None). I can confirm this (when I'm not rushing) but I think it should just be:

for packet in stream.encode():
    container.mux(packet)

... because we should no longer need to call it multiple times to flush either; a single flushing call should clear it out.

Part 2: We still test against 2.6 and 2.7 on Travis. I'm still largely stuck in 2.7 (due to working in the VFX field and that I expect Maya to never upgrade to Python 3).

I imagine once it flushes properly, the video will be as expected.

Part 3: Like you found, we're just using the FFmpeg API in a way they don't like. It is just deprecated, and works fine. It is an annoying message though.

@mikeboers mikeboers added the docs label Jul 18, 2017
@hhsprings
Copy link
Author

Part 1. Originally my question is:

Question: Must we do always "Finish encoding the stream"? If so, how do we write this? And what does it mean?

We need to do this? And flush you mentions is what? PyAV's Container have the method flush? Do you mean "Finish encoding the stream" is for flushing packet? If so, what can I do if I encounter av.AVError?

You might explain this in the context of design of PyAV as developer, if so, in the future we will have no need to "Finish encoding the stream" for flushing?

Part 2:

I imagine once it flushes properly, the video will be as expected.

Do you mean PyAV can fix it or the end-user can fix it?

@mikeboers mikeboers mentioned this issue Aug 27, 2017
10 tasks
@mikeboers mikeboers added triage and removed triage labels Aug 27, 2017
@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants