рассчитать размер файла ответа? - PullRequest
1 голос
/ 02 декабря 2009

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

1 Ответ

1 голос
/ 02 декабря 2009

(Обновлено с окончательным решением конкретной проблемы в нижней части ответа.)

Вы не можете

В этом случае (и в большинстве других случаев) кодирование аудио и видео не предсказуемо, когда речь идет о точном конечном размере файла. Помните тот факт, что характеристика исходного материала и влияние на конечный размер файла не могут быть предсказаны при кодировании. Если вы транскодируете «на лету», вы делаете две вещи: 1) сжатие, 2) потеря данных. Это просто невозможно сделать с выходным форматом mp3.

Вы могли бы ... если : кодирование было без потерь, и ваш алгоритм был настроен на очень специфические характеристики исходного материала (частота выборки, размер выборки и т. Д.) И оба исходные и целевые форматы там, где они не сжаты. Но это не ваша ситуация.

Что касается заголовка: не отправляйте! Заголовок Content-Length не является требованием HTTP 1.1. У этого есть свои недостатки (индикаторы выполнения не могут знать, что сделано на 100% до конца файла; «оставшееся время» также невозможно), но я думаю, что вы можете жить без него.


Окончательное обсуждение на основе комментариев:

С браузером я получаю поведение, которое вы описываете. И с помощью этой команды curl (полезной для отладки низкоуровневой боли, подобной этой) она также не работает:

curl --trace-ascii trace0.txt "http://dmpwap.net/playmp3.php?b=128&file=Red_Hot_Chili_Peppers_-_15_-_Fortune_Faded.mp3" > test0.mp3

Я получаю 0 байтов и вижу это в своем следе:

manoa:~ stu$ cat trace0.txt == Info: About to connect() to dmpwap.net port 80 (#0)
== Info:   Trying 64.191.50.69... == Info: connected
== Info: Connected to dmpwap.net (64.191.50.69) port 80 (#0)
=> Send header, 213 bytes (0xd5)
0000: GET /playmp3.php?b=128&file=Red_Hot_Chili_Peppers_-_15_-_Fortune
0040: _Faded.mp2 HTTP/1.1
0055: User-Agent: curl/7.19.4 (universal-apple-darwin10.0) libcurl/7.1
0095: 9.4 OpenSSL/0.9.8k zlib/1.2.3
00b4: Host: dmpwap.net
00c6: Accept: */*
00d3: 
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 19 bytes (0x13)
0000: Connection: close
<= Recv header, 37 bytes (0x25)
0000: Date: Fri, 11 Dec 2009 14:04:58 GMT
<= Recv header, 27 bytes (0x1b)
0000: Server: Microsoft-IIS/6.0
<= Recv header, 27 bytes (0x1b)
0000: X-Powered-By: PHP/5.2.9-2
<= Recv header, 35 bytes (0x23)
0000: Content-Transfer-Encoding: binary
<= Recv header, 26 bytes (0x1a)
0000: Content-Type: audio/mpeg
<= Recv header, 2 bytes (0x2)
0000: 
<= Recv data, 0 bytes (0x0)
== Info: Closing connection #0

Но ....

Если я добавлю опцию --tcp-nodelay, она будет отлично работать ! E.g.:

curl --tcp-nodelay --trace-ascii trace1.txt "http://dmpwap.net/playmp3.php?b=128&file=Red_Hot_Chili_Peppers_-_15_-_Fortune_Faded.mp3" > test1.mp3

Возвращено 3219104 байта. Trace.txt выглядит так:

== Info: About to connect() to dmpwap.net port 80 (#0)
== Info:   Trying 64.191.50.69... == Info: TCP_NODELAY set
== Info: connected
== Info: Connected to dmpwap.net (64.191.50.69) port 80 (#0)
=> Send header, 213 bytes (0xd5)
0000: GET /playmp3.php?b=128&file=Red_Hot_Chili_Peppers_-_15_-_Fortune
0040: _Faded.mp3 HTTP/1.1
0055: User-Agent: curl/7.19.4 (universal-apple-darwin10.0) libcurl/7.1
0095: 9.4 OpenSSL/0.9.8k zlib/1.2.3
00b4: Host: dmpwap.net
00c6: Accept: */*
00d3: 
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 19 bytes (0x13)
0000: Connection: close
<= Recv header, 37 bytes (0x25)
0000: Date: Fri, 11 Dec 2009 13:56:47 GMT
<= Recv header, 27 bytes (0x1b)
0000: Server: Microsoft-IIS/6.0
<= Recv header, 27 bytes (0x1b)
0000: X-Powered-By: PHP/5.2.9-2
<= Recv header, 35 bytes (0x23)
0000: Content-Transfer-Encoding: binary
<= Recv header, 26 bytes (0x1a)
0000: Content-Type: audio/mpeg
<= Recv header, 2 bytes (0x2)
0000: 
<= Recv data, 1258 bytes (0x4ea)
0000: ID3.......TENC.......Lavf52.23.1...d.... ..=....w......oq......0
   ...  {many lines}
0180: UUUUUU
== Info: Closing connection #0

Я могу слушать песню (3m21s, стерео, mpga, 48kHz, 128kbps) без проблем.

Итак, моя теория такова, что, поскольку в потоке есть последовательные байты 0x00, клиенты думают "Хорошо, я получил 0x00, 0x00 ... и больше ничего не было отправлено, соединение должно быть разорвано . " Но с параметром --tcp-nodelay, установленным на клиенте curl, этого не происходит.

Мой вариант решения: Отключить Алгоритм Нагеля (установить TCP без задержки на опциях сокетов) на стороне сервера, по крайней мере для этих соединений запроса транскодирования. Это предотвратит буферизацию, которая, я подозреваю, приводит к разрыву соединений.

...