1

need your advice.

I have a web-serivice which generates mp3 files out of wavs.

The process of conversion takes time and I want visitor to be able to start listening right away, while the conversion is still going on.

Having tried the html5 tag I found that I can only play the part of mp3 file which was ready at the moment the mp3 file was fetched. I mean, it doesn't seem to care that the file might have grown since it was fetched.

What is the right way to approach this situation?

Thanks in advance for any info.

Sergey Grechin
  • 876
  • 11
  • 14

2 Answers2

0

I believe that you can use JPlayer to play them. One of the features is that it does not preload.

EDIT : The HTML5 audio player also has the preload attribute which can have the following values:

"none": will not prefetch anything

"metadata" (not sure if it's the correct word): will get some basic stuff like length, sample rate

"auto": will prefetch the entire mp3

Limnic
  • 1,826
  • 1
  • 20
  • 45
  • 1
    preload attribute of – Sergey Grechin Apr 12 '14 at 11:23
  • @user1312695 here's also something that might be interesting: [PHP Streaming MP3](http://stackoverflow.com/questions/2358253/php-streaming-mp3) – Limnic Apr 12 '14 at 11:36
  • That guy's problem seems very similar. Thanks for the hint. – Sergey Grechin Apr 12 '14 at 12:02
0

You need to get a bit more control over the serving process, rather than just leaving it up to your web server.

When your web server responds to an HTTP request, it includes a Length: header that tells the client how big the requested resource is, in bytes. Your web server will only send up to the length available at the time of the request, because it doesn't know the file is about to be appended to. The client will download all of that data, but from the client's perspective, it will have downloaded the entire file when really the file wasn't even done being encoded yet.

To work around this issue, you need to pipe the output of your encoder to both a file, and your client at the same time. For the response data to the client, do not include a Length: header at all. Most clients will work with chunked encoding, allowing you to be compliant with HTTP/1.1. Some clients (early Android, old browsers, old VLC) cannot handle chunked encoding, and will just stream the data as it comes in.

How you do this specifically depends entirely on what you're using server-side, which you didn't specify in your question. Personally, I use Node.js for this as it makes the process very easy. You can simply pipe to both streams. Be careful that if you use the multiple pipe method, the pipes only run as fast as the slowest. Some streaming clients (such as VLC) will lower the TCP window size to not allow too much data to have to be buffered client-side. When this occurs, your writes to disk will run at the speed of the client. This may not matter to you, but it is something to be aware of.

Brad
  • 159,648
  • 54
  • 349
  • 530
  • Thanks, that's exactly what I'll do (and it proves working in my prototype). Instead of referencing a file directly, I'll make something like stream.php?file=/mp3/123.php which will stream the file as it is being created. And it will send the final "Lneght:", fortunatelly, the size of mp3s are known (not using variable bitrate). The only thing which sort of worries me is execution time limit, if a file is being built for, let's say, a minute, then it means the corresponding process of stream.php will be alive for quite a long. Is there any way around excep server reconf? – Sergey Grechin Apr 16 '14 at 18:49
  • @user1312695 The size of your MP3s are not known exactly. While CBR is very close to the bitrate specified, it is never exact, and therefore unsuitable for predicting a length header. Leave that length header off completely. – Brad Apr 16 '14 at 18:50
  • Strangely, in my experiments, CBR for wavs of the same length always gives the files of the same size, up to a byte. I use lame encoder with default settings. Anyway, without the header, how will the client know that there is no more data to expect? – Sergey Grechin Apr 16 '14 at 19:23
  • @user1312695 The client knows there is no more data when the server closes the TCP connection. – Brad Apr 16 '14 at 22:36