php - reproducir - La duración del audio HTML5 para mp3 siempre es Infinity
insertar audio mp3 en html (1)
Finalmente encontré mi solución aquí . Tuve que cambiar ligeramente el código, y aquí están los cambios. Ahora, si puedo admitir completamente varios rangos, estará completo.
(Estoy compartiendo esto porque todo lo que veo son respuestas incompletas. Afortunadamente, también ayudará a alguien).
$file = $basePath . $media->getFileName();
$fileSize = filesize($file);
$fileTime = date(''r'', filemtime($file));
$fileHandle = fopen($file, ''r'');
$rangeFrom = 0;
$rangeTo = $fileSize - 1;
$etag = md5(serialize(fstat($fileHandle)));
$cacheExpires = new /DateTime();
if (isset($_SERVER[''HTTP_RANGE''])) {
if (!preg_match(''/^bytes=/d*-/d*(,/d*-/d*)*$/i'', $_SERVER[''HTTP_RANGE''])) {
$statusCode = 416;
} else {
$ranges = explode('','', substr($_SERVER[''HTTP_RANGE''], 6));
foreach ($ranges as $range) {
$parts = explode(''-'', $range);
$rangeFrom = intval($parts[0]); // If this is empty, this should be 0.
$rangeTo = intval($parts[1]); // If this is empty or greater than than filelength - 1, this should be filelength - 1.
if (empty($rangeTo)) $rangeTo = $fileSize - 1;
if (($rangeFrom > $rangeTo) || ($rangeTo > $fileSize - 1)) {
$statusCode = 416;
} else {
$statusCode = 206;
}
}
}
} else {
$statusCode = 200;
}
if ($statusCode == 416) {
$response = $this->getResponse();
$response->setStatusCode(416); // HTTP/1.1 416 Requested Range Not Satisfiable
$response->addHeaderLine(''Content-Range'', "bytes */{$fileSize}"); // Required in 416.
} else {
fseek($fileHandle, $rangeFrom);
set_time_limit(0); // try to disable time limit
$response = new Stream();
$response->setStream($fileHandle);
$response->setStatusCode($statusCode);
$response->setStreamName(basename($file));
$headers = new Headers();
$headers->addHeaders(array(
''Pragma'' => ''public'',
''Expires'' => $cacheExpires->format(''Y/m/d H:i:s''),
''Cache-Control'' => ''no-cache'',
''Accept-Ranges'' => ''bytes'',
''Content-Description'' => ''File Transfer'',
''Content-Transfer-Encoding'' => ''binary'',
''Content-Disposition'' => ''attachment; filename="'' . basename($file) .''"'',
''Content-Type'' => ''audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3'', // $media->getFileType(),
''Content-Length'' => $fileSize,
''Last-Modified'' => $fileTime,
''Etag'' => $etag,
''X-Pad'' => ''avoid browser bug'',
));
if ($statusCode == 206) {
$headers->addHeaderLine(''Content-Range'', "bytes {$rangeFrom}-{$rangeTo}/{$fileSize}");
}
$response->setHeaders($headers);
}
return $response;
Estoy jugando con mi proyecto favorito y, experimentando con la "transmisión" mp3 con PHP, siempre recibo la duración del audio para devolver Infinity
. Intenté buscar en muchos lugares, desafortunadamente, parece que no puedo encontrar el problema de raíz.
Tenga en cuenta que tuve que dejar de lado ese proyecto por un tiempo, y todo funcionó bien antes. Cuando reinicié el trabajo en el proyecto, hice algo de refactor de UI y descubrí este "error". ¿Alguien puede detectar algo mal con mi código?
Contexto: se trata de una acción de controlador (ZF2), donde $media
es un modelo POPO .
$file = $basePath . $media->getFileName();
$fileSize = filesize($file);
$fileHandle = fopen($file, ''r'');
$etag = md5(serialize(fstat($fileHandle)));
$cacheExpires = new /DateTime();
// TODO : implement ranges...
if ( isset($_SERVER[''HTTP_RANGE'']) ) {
// find the requested range
// this might be too simplistic, apparently the client can request
// multiple ranges, which can become pretty complex, so ignore it for now
preg_match(''/bytes=(/d+)-(/d+)?/'', $_SERVER[''HTTP_RANGE''], $matches);
$rangeFrom = intval($matches[1]);
$rangeTo = intval($matches[2]);
$statusCode = 206;
} else {
$rangeFrom = 0;
$rangeTo = $fileSize;
$statusCode = 200;
}
fseek($fileHandle, $rangeFrom);
set_time_limit(0); // try to disable time limit
$response = new Stream();
$response->setStream($fileHandle);
$response->setStatusCode($statusCode);
$response->setStreamName(basename($file));
$headers = new Headers();
$headers->addHeaders(array(
''Pragma'' => ''public'',
''Expires'' => $cacheExpires->format(''Y/m/d H:i:s''),
''Cache-Control'' => ''no-cache'',
''Accept-Ranges'' => ''bytes'',
''Content-Description'' => ''File Transfer'',
''Content-Transfer-Encoding'' => ''binary'',
''Content-Disposition'' => ''attachment; filename="'' . basename($file) .''"'',
''Content-Type'' => ''audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3'', // $media->getFileType(),
''Content-Range'' => "bytes {$rangeFrom}-{$rangeTo}/{$fileSize}",
''Content-Length'' => $fileSize,
''Etag'' => $etag,
''X-Pad'' => ''avoid browser bug'',
));
$response->setHeaders($headers);
return $response;
He intentado jugar con casi todos los campos HEADER (incluso eliminando los rangos), pero el navegador siempre obtiene isFinite(audio.duration) === false
. Todo lo demás parece funcionar, incluida la reproducción, sin problemas.