Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    NewUserHa
    @NewUserHa
    the latency = the %{localtime} in ffplay -i testsrc and ffplay udp://
    is it because that the PYTHON is slow?
    arsserpentarium
    @arsserpentarium
    Hello. Do anybody have example, how to record video with sound?
    quantotto
    @quantotto
    @NewUserHa it is probably less about Python, but more about encoding speed. If your encoding pipeline is slow indeed, most of the chances it is CPU bound. Check if you have one of the cores maxed out at 100% while running your code. I saw similar issues on weaker machines, like Raspberry Pi.
    NewUserHa
    @NewUserHa
    @quantotto But no, overall cpu usage ~40%, and all logical core usage <70%.
    @quantotto would you like to try that code?
    quantotto
    @quantotto
    @NewUserHa do I just replace 224.0.0.1 with localhost?
    quantotto
    @quantotto
    @NewUserHa I am not sure how graphs work exactly in AV, but it is probably some logic issue rather than performance. If you change rate to 2 from 30 everything becomes even slower. So, it seems that rate affects how often new frames are pushed and the localtime remains the same even longer than with rate 30. I'd check this rate logic.
    Zeyu Dong
    @dong-zeyu

    Hello everyone, I have problem trying to remux a raw h264 stream to mp4. That is what I'm currently dong.

    avin = av.open("test.h264", "r", "h264")
    avout = av.open("test.mp4", "w", "mp4")
    s = avout.add_stream(template=avin.streams[0], rate=30)
    for pkt in avin.demux():
        pkt.stream = s
        avout.mux(pkt)
    avin.close()
    avout.close()

    However, when I read the output file using ffprobe test.mp4, the stream info shows

    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 720x480, 278198 kb/s, 10868.85 fps, 12800 tbr, 12800 tbn, 25600 tbc (default)

    The fps is too large to play.
    It seems that raw h264 stream dose not contain the information of the fps and pts data, but I know the actual fps is 30. How to tell the demuxer this information?

    Nitan Alexandru Marcel
    @nitanmarcel
    I've got a small problem with av.open. I'm passing to it an audio stream from fmstream.org and the container reaches eof early and the stream stops. Am I doing something wrong or?
    quantotto
    @quantotto
    @dong-zeyu yes, you have to calculate pts / dts yourself. Something like below worked for me:
    import av
    avin = av.open("test.264", "r", "h264")
    avout = av.open("test.mp4", "w", format="mp4")
    avout.add_stream(template=avin.streams[0])
    time_base = int(1 / avin.streams[0].time_base)
    rate = avin.streams[0].base_rate
    ts_inc = int(time_base / rate)
    ts = 0
    for pkt in avin.demux():
        pkt.pts = ts
        pkt.dts = ts
        avout.mux(pkt)
        ts += ts_inc
    avin.close()
    avout.close()
    @nitanmarcel could you share what exactly are you trying to open? which URL etc. Basically, code snippet that doesn't work
    Nitan Alexandru Marcel
    @nitanmarcel
    And about the snippet I removed it but I haven't set an out file instead I've tried to read it frame by frame
    The library I want to use pyav is called tgcalls and here's an example on how it should be used https://github.com/MarshalX/tgcalls/blob/main/examples/restream_using_raw_data.py
    NewUserHa
    @NewUserHa
    @quantotto maybe the pts problem may also solve by filter fps or encoder fps=
    @nitanmarcel the ffmpeg cli may work in that case
    Nitan Alexandru Marcel
    @nitanmarcel
    NewUserHa
    @NewUserHa
    @quantotto no need to replace 224.0.0.1 which is a multicast address and should work fine on most situations for udp
    if slow down the testsrc rate, then the while loop is also be slowed down. so it can also help solve this issue if it's really because the Python is slow.
    should consider other languages maybe I guess?
    Nitan Alexandru Marcel
    @nitanmarcel
    @NewUserHa i know as I'm already using the cli, I'm just looking for alternatives ^^
    NewUserHa
    @NewUserHa
    pyav has issues like the issue I encounter..
    but PYAV transferring audio shouldn't have any issue
    but if you want to read frame by frame, I guess you should caution overflow of ffmpeg libs(PYAV depends) internal's buffer
    Nitan Alexandru Marcel
    @nitanmarcel
    Oh, actually I haven't though of exploring projects that uses pyav, but most probably most of them are about converting files rather than reading from live streams
    NewUserHa
    @NewUserHa
    no. pyav has many streaming use cases as you can see on github issue tracker
    quantotto
    @quantotto
    Whatever works from ffmpeg cli will work through pyav as well. Just need to make sure correct options are supplied and, in some cases, things like pts / dts need to be set manually.
    NewUserHa
    @NewUserHa
    maybe pull from testsrc is using python's main thread??
    quantotto
    @quantotto
    @NewUserHa I don't think that this is the case of slow Python (thought I might be wrong). Most of the processing is happening in libav libraries (in C/C++). It is something related to logic of the graph.
    NewUserHa
    @NewUserHa
    the videoframe pulled from libav is in python's object form which is slow
    and change src rate from 30 to 2 solving the issue may also indicate the reason?
    quantotto
    @quantotto
    @NewUserHa did rate change solve the issue? I saw that localtime lagging even more, but it could be that I didn't run it properly. I didn't have too much time to invest in it
    NewUserHa
    @NewUserHa
    heard you said change src rate from 30 to 2 solving the issue..
    will try to change it to 60 fps later.
    quantotto
    @quantotto
    @NewUserHa what i said: "If you change rate to 2 from 30 everything becomes even slower."
    NewUserHa
    @NewUserHa
    the localtime difference is different with pts difference, also different with frame.
    but from the frame number, the video does delay, but not that much as localtime showed. and pts slower than other's changes is also weired
    quantotto
    @quantotto
    @nitanmarcel the following works fine for me and not reaching end of file. It continuously reads packets from the stream. I had to stop it with CTRL-C; otherwise, it runs endlessly.
    >>> import av
    >>> a = av.open("https://stream.live.vc.bbcmedia.co.uk/bbc_radio_one")
    >>> s = a.streams.audio[0]
    >>> s
    <av.AudioStream #0 mp3float at 48000Hz, stereo, fltp at 0x1c4ce7a9940>
    >>> for pkt in a.demux(s):
    ...     print(pkt.pts)
    ...
    0
    338688
    677376
    1016064
    1354752
    1693440
    2032128
    2370816
    2709504
    ...
    Nitan Alexandru Marcel
    @nitanmarcel
    Thanks I'll try to experiment with that. One last question tho: Calling a.close() will stop the outgoing process?
    quantotto
    @quantotto
    @nitanmarcel a.close() closes file object that you read / write or network connection of streaming. Not sure what you mean by "outgoing process"
    Nitan Alexandru Marcel
    @nitanmarcel
    Ah thanks. I just want to stop the stream without having to ctrl+c
    quantotto
    @quantotto
    You can also break the loop when needed and stop reading packets from demux generator and then call close.
    Nitan Alexandru Marcel
    @nitanmarcel
    @quantotto so I started with something like this:
    async def _start_av(self): input_ = await run_in_executor(av.open, self.url, options={"format": "s16le", "acodec": "pcm_s16le", "ac": "2", "ar": "48k"}) for frame in input_.decode(): if frame: self._fifo.write(frame)
    wait

    So I've started with something like this:

    self._fifo = av.AudioFifo(format="s16le")
    
    def _start_av(self):
    input_ = av.open(self.url, options={"format": "s16le", "acodec": "pcm_s16le", "ac": "2", "ar": "48k"})
    for frame in input_decode():
        if frame:
            self._fifo.write(frame)
    
    def read(self, length):
        data = self._fifo.read(length)
        if data:
            data = data.to_ndarray().tobytes()
        return data # returns the data to the library

    But I have a small problem, the data received from the AudioFifo is bigger than the one requested

    or wait, maybe I'm getting the AudioFifo wrong
    Nitan Alexandru Marcel
    @nitanmarcel
    Wait, can in this example self._fifo be any object that has a write method similar to bytesio?
    quantotto
    @quantotto
    @nitanmarcel I am not sure I have the full context of how you obtain length, who calls read etc.
    Nitan Alexandru Marcel
    @nitanmarcel
    @quantotto it's a library that requires raw data in pcm 16bit 48k so the length is returned by the library and it indicates the exact length of bytes it needs to properly play.
    The read function is called every time by the library when a set of bytes are played
    And what I'm looking for is to use pyav to format any audio from an url (it can also be an ytdl url) to the required format and feed it to the library and all of this while keeping the memory clean.
    quantotto
    @quantotto
    @nitanmarcel I read about AudioFifo in docs and it could be that you use length incorrectly. AudioFifo.read method expects number of samples to read. You mentioned that the library supplying length expects length amount of bytes. With Audio, amount of samples is not equal to amount of bytes. For example, in your case, pcm_s16le means that each sample is 16 bit little endian and this is 2 bytes per sample. If library is indeed supplying to you number of bytes it expects, you need to read length / 2 number of samples. With that, I hope the library is aligned with audio realities and asks for number of samples.