Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#748 closed defect (invalid)

server aborts mp3 download after 1-2min, try reconnecting

Reported by: blarson Owned by:
Priority: normal Component: avformat
Version: 0.8.7 Keywords: mp3, http
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Sorry for the duplicate messages - I asked about this on irc last night, and didn't get an answer, so posted it to the mailing list. Then burek suggested I file a bug report.

I'm trying to build a simple Android streamer using ffmpeg. Everything is working well, except that for some mp3 streams av_read_frame() returns an error (-541478725) after playing for 1-2 minutes. The same problem happens when using ffplay in Linux (0.8.6)

The stream plays fine with Chrome. Also I can download the mp3 and then it plays fine with ffplay.

One example bad stream is http://www.stationcaster.com/clicktrack/index.mp3?media=%2Fstations%2Fwhb%2Fmedia%2Fmp3%2FDoug_Farrar-1323805825.mp3&usecat=373&subscribed=true&title=Doug+Farrar&ext=.mp3

Once av_read_frame returns an error, it never works again until I restart the stream. Worst-case, is there any way to skip past and keep playing?

Change History (14)

comment:1 Changed 7 years ago by Cigaes

You should use av_strerror, you would have noticed that -541478725 is AVERROR_EOF: lavf considers that your file has ended.

This seems perfectly normal with the URL you give as an example, as it is in fact a redirection to short individual files.

comment:2 Changed 7 years ago by blarson

Cigaes, thank you so much for your help. Please forgive my inexperience with lavf, I'll be sure to use av_strerror next time.

I'm a little confused - if the URL is a redirection to short individual files, how can I play them all in a row? I can download the URL in my browser and I get a full 21:52 MP3 file at 7.5MB. Also the estimated duration in ffplay and my Android app is the same 21 minutes 52 seconds.

What tool are you using to see that the URL is a redirection to short individual files? Is it possible to play them as one stream in ffplay and/or using lavf?

Thanks again, your help is incredibly appreciated!

comment:3 Changed 7 years ago by Cigaes

Well, I get the same 7.5 Mo file than you, and curl shows me that the actual URL is http://www.stationcaster.com/stations/whb/media/mp3/Doug_Farrar-1323805825.mp3.

A 7.5 Mo file is what I call a short, individual file, as opposed to streaming, which is supposed to go on forever.

Now, if your Android app is interrupted sooner than that, then I suspect some kind of stupid handling of network errors at the Android level. You should try calling the avio_read function directly to see how the file data downloads and at what point an error is reported, and what kind of error.

comment:4 Changed 7 years ago by blarson

Ah I see... yes it is definitely a short file at ~22 minutes compared with an indefinite stream.

I suspected Android network issues as well, except that the same problem happens with ffplay on my desktop. After 1-2 minutes both platforms report AVERROR_EOF when streaming. ffplay works fine if I pass it the pre-downloaded mp3 file.

comment:5 Changed 7 years ago by Cigaes

I see. Maybe you should not have talked about Android at all, it made the discussion murky.

The problem is that:
ffmpeg -i $url -y t.wav
succeeds while:
ffmpeg -re $url -y t.wav
fails.

The same happens with "curl $url | slowcat" (slowcat is a small custom program): therefore, it seems a case of bogus web server that closes the connection before it is complete if the receiving end is not fast enough.

comment:6 Changed 7 years ago by blarson

Ah perfect! Thank you so much! It looks like Chrome is downloading the file as fast as possible in the background, while ffplay/my app is just streaming it as needed with a small buffer.

I'm sorry for the confusion I caused mentioning Android.

I'll see if the webserver can be changed to support this, but it sounds like the best bet is for me to try and do what Chrome does and download the full file in the background. I'll also dig in to what ffmpeg does with the -i vs -re arguments.

Your help has been invaluable! Thank you so much!!

comment:7 Changed 7 years ago by Cigaes

-i is just the option to select the input URL. -re tells ffmpeg to work slower than it could to emulate the speed of the contents itself.

If you control the web server, then you really must fix it, it will cause other problems than that, and fixing it will help you regulate your bandwidth.

But you need _also_ to work around the problem in your program. For that, you need two things:

  • A bigger buffer than the small one inside lavf: you do not need the whole file, but mobile apps should be able to handle a few seconds of network hiccup.
  • A reconnect feature: if the stream ends before it should, create a new one and seek to the last position.

Note that both the buffer and the reconnect would IMHO be valuable additions to ffmpeg's API.

comment:8 Changed 7 years ago by blarson

I think both of your suggestions make perfect sense. For the larger buffer, can this be done internally to lavf? Or should I download to a separate buffer and point lavf to that external buffer?

Specifically, would it be easier/possible to use a custom reader in my input context and keep the larger buffer there? And if so, can I still use lavf code to download the file?

comment:9 Changed 7 years ago by reimar

I think ffmpeg now has a cache:// protocol which may or may not be exactly the right thing.

comment:10 Changed 7 years ago by michael

I agree, the cache protocol is the right thing to use but, it doesnt yet have a background thread filling the buffer, which it would need for this so its a patch welcome thing.

comment:11 Changed 7 years ago by blarson

Sorry again for my inexperience, where can I find out more about the cache:// protocol? Is it the same as ICS (http://en.wikipedia.org/wiki/Internet_Cache_Protocol)? Does it require server-side support?

comment:12 Changed 7 years ago by michael

  • Keywords mp3 http added; av_read_frame ffplay removed
  • Resolution set to needs_more_info
  • Status changed from new to closed
  • Summary changed from av_read_frame() returns error while streaming mp3 to server aborts mp3 download after 1-2min, try reconnecting

Neither of the 2 URLs works anymore (404) thus theres no testcase to implement reconnect anymore. Without a testcase we cannot fix this, thus closing. If someone has/finds a url with a similar problem or better someone has a actual patch that implements reconnect+seek then please reopen.

comment:13 Changed 7 years ago by blarson

I apologize for not updating this ticket. We contacted the server admins and found an issue with their setup where they would drop connections after a few minutes, so streaming files would have issues. Some other players would quickly download the whole file in the background and didn't run into this problem, but we never implemented that logic in our custom player.

This issue can be closed, it is not a bug with ffmpeg.

comment:14 Changed 7 years ago by llogan

  • Resolution changed from needs_more_info to invalid
Note: See TracTickets for help on using tickets.