bvibber / OGVKit

Ogg and WebM media playback for iOS
MIT License
216 stars 67 forks source link

Start Playback Mid-File #182

Closed AlexEKoren closed 4 years ago

AlexEKoren commented 7 years ago

Hey there, I've written my own subclass of OGVInputStream which reads from a TCP socket. It takes bytes as it comes in from the TCP socket and adds them to the buffer then presents them through the "readBytes: blocking:" method. I turn off seeking and I basically get a livestream as long as the server starts serving the WebM file from the beginning of the file.

However, the client may connect to the server in the middle of the WebM playback meaning it doesn't get headers associated with the file. Is there anyway to make sure the player waits for a Keyframe or something? Right now I'm getting a "nestegg_init" failed and then a "Error processing header state. :(" which I'm guessing occurs because it doesn't see the beginning of the file.

I'm not overly familiar with VP9 and WebM formats, but from what I've read it should be possible if the player is pointed at certain frames. I'm happy to wait for some sort of byte pattern and play from there or maybe there's a settings, I'm just not sure what to look for.

bvibber commented 7 years ago

A couple thoughts:

So you've got two basic problems to solve:

If you can serve out the header bits from a separate file or something that should work. If you have live streams with predictable formatting, you could probably pre-generate a header set too.

If you have pre-existing files you're serving out, you might benefit from using ffmpeg to generate MPEG-DASH manifests -- see http://wiki.webmproject.org/adaptive-streaming/instructions-to-playback-adaptive-webm-using-dash -- as that manifest file should list things like the size of the headers/'start codes'.

As for cluster boundaries, there should be a predictable bit pattern in the WebM/Matroska stream. See https://www.webmproject.org/docs/container/ etc for details on that; I haven't attempted this exact process so don't have a bit pattern handy to recommend. :)

AlexEKoren commented 7 years ago

Hey, so I managed to get the library playing data sent over TCP that may start in the beginning or middle of the VP9 stream. However, it seems to take the player a while to start playing (usually around 30s which seems pretty long...)

I buffer 5s worth of data from the TCP stream before setting the state to OGVInputStreamStateReading. I can't tell, but is there anything going on internally in OGVKit that would be creating a greater delay? I'm making sure to call from the main thread and that there's always data when it's requesting it.

I also noticed that the library does a lot of 1 byte calls to

readBytes: blocking:

Is there any reason that's the case? Could it be a bug that shouldn't be occurring? Length = 1 byte is hard coded into some of the nestegg commands, but I'm not 100% sure why.