Author Topic: User file stream prematurely ends (testable code included)  (Read 171 times)

yncat

  • Posts: 6
Hello.

I'm trying to fetch an mp4 stream from a livestreaming website and play it with BASS's user file stream in realtime.
When I download the file to my local storage and play it using a media player or BASS_StreamCreateFile, the file is normally played.
However, when using BASS_StreamCreateFileUser, the stream suddenly ends, despite the fact that the file content is longer. It results in changing the stream status to BASS_ACTIVE_STOPPED, and trying to forcefully replay it causes BASS_ERROR_UNKNOWN.
The website might be feeding fragmented mp4's, but if that's the case, it's unexplainable that BASS_StreamCreateFile can play it normally.

I've prepared some code snippets and sample mp4 data which can reproduce the issue.

Can anyone give me some pointers where I can solve this issue? Or is it something to do with BASS's internal processing?

https://www.dropbox.com/s/3563lwlfk4vcdu1/play-livestream-test.zip?dl=0

This code works with Python 3.8.
No external dependencies are required. Everything is included in the zip archive.

Ian @ un4seen

  • Administrator
  • Posts: 23640
Please give this latest BASS build a try and see if it makes any difference:

   www.un4seen.com/stuff/bass.zip

yncat

  • Posts: 6
Hello.
I've overwritten the new bass.dll provided, but the result seems to  be exactly same.
I've also checked if my code is loading the expected dll(testing directory/bass/bass.dll), since Windows sometimes tries to load dll's from system directories. I renamed the dll name to random one and confirmed that the test program raised an error, meaning that it tried to load what I expected to be loaded.
(I've also updated the testable code archive)

Ian @ un4seen

  • Administrator
  • Posts: 23640
I'm not a Python user myself, so I couldn't run your exact code, but I tried similar C/C++ code and I found that the problem is the Media Foundation MP4 decoder/parser is trying to seek in the file, which isn't possible when it's a buffered stream (STREAMFILE_BUFFER/PUSH) with indeterminate length. But here's a BASS update that adds some support for that (eg. it will read ahead to the requested position):

   www.un4seen.com/stuff/bass.zip

Please give that a try and let me know how it goes in your tests.

yncat

  • Posts: 6
Thank you for debugging and adding support for the problem.
Using the updated version, I was able to play the file I had posted first correctly.
However, when another sample mp4 is used, it stopped again.
This is the new archive which includes the sample which BASS couldn't handle.
https://www.dropbox.com/s/pia1ipbdzvjmzbv/play-livestream-test2.zip?dl=0
If Windows Media Foundation wants the real EOF, is it difficult to stream mp4 with undetermined length at the moment?

Ian @ un4seen

  • Administrator
  • Posts: 23640
It isn't so much about the EOF. The main issue is that the Media Foundation MP4 decoder/parser is also seeking backwards sometimes, while BASS doesn't keep old (already used) data from an indeterminate length stream, ie. old data is replaced by new data in the buffer. The BASS update above added the ability to keep some old data to allow seeking backwards, but your 2nd file requires seeking further back than the 1st file did, so it needs even more old data. Here's another update that will keep more old data, for you to try:

   www.un4seen.com/stuff/bass.zip

Btw, it looks like this seeking only happens with fragmented MP4 files/streams.

yncat

  • Posts: 6
Thank you for your reply.
Now I understand what the decoder / parser is doing.
The updated BASS successfully handled the example mp4 file and it made longer playback possible when used for the real stream, but it looks like larger seeking back occasionally occurs, and when it happens, BASS stops playback.
I haven't fully understood the format of fragmented mp4's though, I'm concerning that the amount of backward seeking is dynamically determined and depends on the header info e.g. like size of each fragment. Or it might be seeking back to the header (called media initialization section apparently) every time when it reaches the end of a fragment.
ref 1: https://datatracker.ietf.org/doc/html/rfc8216#section-3.3
ref 2: https://hlsbook.net/hls-fragmented-mp4/
I'm not 100% sure if my understanding is right, and even if it's close or correct, I don't know how hard adding the handling to BASS is.