HTML5 audio duration for mp3 is always Infinity

后端 未结 1 651
轮回少年
轮回少年 2020-12-17 06:52

I\'m playing with my pet project and, experimenting with mp3 \"streaming\" with PHP, I always get the audio duration to return Infinity. I\'ve try to search in

1条回答
  •  轮回少年
    2020-12-17 07:39

    I finally found my solution here. I had to slightly change the code, and here are the changes. Now, if I can fully support multiple ranges, it'll be complete.

    (I'm sharing this because all I see are incomplete answers. Hopefully, it will also help someone too.)

    $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;
    

    0 讨论(0)
提交回复
热议问题