Длительность передачи при потоковой передаче mp3 с сервера на html5 audio

У меня есть узел.JS сервер преобразования и потоковой передачи mp3 на лету. Я использую тег HTML5 audio для использования этого потока, и проблема, с которой я сталкиваюсь, заключается в том, что аудиоэлемент не знает продолжительности mp3, пока он не закончит воспроизведение всего этого (очевидно). Есть ли способ, так как мой сервер знает продолжительность mp3 перед отправкой, что я могу включить продолжительность в заголовок ответа с сервера или что-то еще, поэтому клиент, потребляющий его, знает продолжительность?

спасибо

3 ответов


Я думаю, что в настоящее время, с точки зрения широко поддерживаемого решения, вы застряли, отправляя этот материал через отдельный запрос (или иначе в каком-то манифесте ваших ссылок-включенном в список воспроизведения, который вы используете, чтобы указать на соответствующие URI, например). Это, конечно, может быть сгенерировано вашим сервером динамически, когда песни сначала добавляются, а затем обслуживаются статически.

в медиаплеере, который я создаю, я делаю что - то подобное к этому -- загрузка файла json, который содержит то, что обычно находится внутри .метаданные mp3 (которые также будут поддерживать версии без mp3 и т. д.).

Это далеко не идеально, но опять же одна из тех вещей, которые html5 audio/video не должен был решать в своей первой итерации.


года полтора, но я только что столкнулся с этим на прошлой неделе так...

добавить 206 Частичное Содержимое поддержка реализации HTTP-сервера, и эта проблема исчезнет. Поиск внутри контента тоже начинает работать..

аудио и видео html5 теги делают ряд запросы:

Range: bytes=0-  or..
Range: bytes=0-12345

важные биты правильного ответа из spec:

HTTP/1.1 206 PARTIAL CONTENT
Accept-Ranges: bytes
Content-Range: bytes 0-12345

без ответа 206 код, вы получите поведение, которое вы испытываете.

Я делаю это в Perl так, где $request содержит заголовки запросов от клиента, нормализованные. Например, SERVER_PROTOCOL в большинстве случаев содержит 'HTTP / 1.1'

my $crlf = "2";
if ( $request->{RANGE} && $request->{RANGE} =~ /bytes=(\d*)-(.*)$/ ) {
    $offset = ;
    $end =  || $size; # end is optional in the spec.  Default to size.
    $header = $request->{SERVER_PROTOCOL} . ' 206 PARTIAL CONTENT' . $crlf .
    'Content-Range: bytes ' . $offset . '-' . $end . '/' . $size . $crlf;
} else {
    $header = $request->{SERVER_PROTOCOL} . ' 200 OK' . $crlf;
}
my $left = $end - $offset;
$header .= 'Server: ' . $SERVER_NAME . $crlf .
    'Accept-Ranges: bytes' . $crlf . 
    'Date: ' . $http_date . $crlf .
    'Content-Type: ' . ($self->simplemime($raw_path) || magic($fh)) . $crlf .
    'Last-Modified: ' . $http_date . $crlf .
    'Content-Length: ' . $size . $crlf .
    'Connection: Keep-Alive' . $crlf .
    'Cache-Control: max-age=' . $EXPIRE . $crlf . $crlf;

вы, конечно, должны выполнить запрос, предоставив соответствующий диапазон байтов для запрашиваемого содержимого.
Клиент часто также "останавливает" загрузку, чтобы соответствовать скорости воспроизведения, поэтому правильный сервер, управляемый событиями такие как Mojolicious, AnyEvent или узел.JS будет масштабироваться, в то время как 1 поток на модель подключения, такую как PHP, нет. (ну, я полагаю,Храповой бы с некоторым взломом, или используя Xsendfile)

кстати, большинство просит диапазона в конечном итоге просто:

Range: bytes=0- 

что переводится, до тех пор, пока они не могут искать и кэширование отключено (и браузер фактически исполняет..), вы на самом деле может сойти с рук, просто переписав заголовок обычного HTTP / 1.1 200 ответ на важные биты HTTP / 1.1 206 ответ, и он работает для некоторые содержание. В частности, это работает для контента, который не имеет необходимых метаданных в конец из файла. Для этих типов файлов я видел запросы диапазона, которые стремятся к концу, а затем перезапускаются в начале файла. По этой причине, лучше всего реализуйте фактический поиск, но вышеперечисленное работает... Используйте на свой страх и риск.


посмотреть здесь : аналогичный вопрос

Я думаю, это то, что вы ищете.