php HTML5 ऑडियो iOS में "लाइव प्रसारण" कहता है जब यह एक स्थिर फ़ाइल है




laravel audio (2)

वाह, यह हल करने के लिए एक बहुत ही कठिन समस्या थी। (मुझे दिन लग गए।)

और मुझे पता चला कि यह सिर्फ iOS नहीं था जिसमें समस्याएं थीं: मैक पर सफारी या तो काम नहीं कर रही थी।

अब मुझे लगता है कि मेरे द्वारा परीक्षण किए गए प्रत्येक ब्राउज़र पर सब कुछ काम करता है।

मुझे वास्तव में खुशी है कि मैंने इस उदाहरण का अनुसरण किया।

यहाँ मेरा जवाब है:

/**
 * 
 * @param string $disk
 * @param string $filename
 * @return \Illuminate\Http\Response|\Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\StreamedResponse
 */
public static function getMediaFile($disk, $filename) {
    $rangeHeader = request()->header('Range');
    $fileContents = Storage::disk($disk)->get($filename);
    $fullFilePath = Storage::disk($disk)->path($filename); //https://stackoverflow.com/a/49532280/470749
    $headers = ['Content-Type' => Storage::disk($disk)->mimeType($fullFilePath)];
    if ($rangeHeader) {
        return self::getResponseStream($disk, $fullFilePath, $fileContents, $rangeHeader, $headers);
    } else {
        $httpStatusCode = 200;
        return response($fileContents, $httpStatusCode, $headers);
    }
}

/**
 * 
 * @param string $disk
 * @param string $fullFilePath
 * @param string $fileContents
 * @param string $rangeRequestHeader
 * @param array  $responseHeaders
 * @return \Symfony\Component\HttpFoundation\StreamedResponse
 */
public static function getResponseStream($disk, $fullFilePath, $fileContents, $rangeRequestHeader, $responseHeaders) {
    $stream = Storage::disk($disk)->readStream($fullFilePath);
    $fileSize = strlen($fileContents);
    $fileSizeMinusOneByte = $fileSize - 1; //because it is 0-indexed. https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16
    list($param, $rangeHeader) = explode('=', $rangeRequestHeader);
    if (strtolower(trim($param)) !== 'bytes') {
        abort(400, "Invalid byte range request"); //Note, this is not how https://stackoverflow.com/a/29997555/470749 did it
    }
    list($from, $to) = explode('-', $rangeHeader);
    if ($from === '') {
        $end = $fileSizeMinusOneByte;
        $start = $end - intval($from);
    } elseif ($to === '') {
        $start = intval($from);
        $end = $fileSizeMinusOneByte;
    } else {
        $start = intval($from);
        $end = intval($to);
    }
    $length = $end - $start + 1;
    $httpStatusCode = 206;
    $responseHeaders['Content-Range'] = sprintf('bytes %d-%d/%d', $start, $end, $fileSize);
    $responseStream = response()->stream(function() use ($stream, $start, $length) {
        fseek($stream, $start, SEEK_SET);
        echo fread($stream, $length);
        fclose($stream);
    }, $httpStatusCode, $responseHeaders);
    return $responseStream;
}

विंडोज क्रोम (और शायद कई अन्य ब्राउज़रों के लिए), यह कोड एक audio तत्व में एक एमपी 3 की सेवा के लिए काम करता है:

/**
 * 
 * @param string $filename
 * @return \Illuminate\Http\Response|\Illuminate\Contracts\Routing\ResponseFactory
 */
public function getMp3($filename) {
    $fileContents = Storage::disk(\App\Helpers\CoachingCallsHelper::DISK)->get($filename);
    $fileSize = Storage::disk(\App\Helpers\CoachingCallsHelper::DISK)->size($filename);
    $shortlen = $fileSize - 1;
    $headers = [
        'Accept-Ranges' => 'bytes',
        'Content-Range' => 'bytes 0-' . $shortlen . '/' . $fileSize,
        'Content-Type' => "audio/mpeg"
    ];
    Log::debug('$headers=' . json_encode($headers));
    $response = response($fileContents, 200, $headers);
    return $response;
}

लेकिन जब मैं उसी पृष्ठ पर ब्राउज़ करने के लिए एक iPhone का उपयोग करता हूं, तो एमपी फ़ाइल कुल अवधि नहीं दिखाती है, और जब मैं इसे खेलता हूं, तो यह "लाइव प्रसारण" कहता है।

मैंने इस प्रश्न के विभिन्न उत्तरों ( एचटीएमएल 5 <ऑडियो> सफारी लाइव प्रसारण बनाम नहीं ) और मेरे द्वारा पढ़े गए अन्य लेखों के सुझावों का पालन करने की कोशिश की है, लेकिन किसी को भी कोई प्रभाव नहीं लगता है।

कोई फर्क नहीं पड़ता कि मैं हेडर कैसे बदलता हूं, एमपी 3 विंडोज पर वांछित कार्य करता है और आईओएस पर काम नहीं करता है।

मैं कैसे गलत कर सकता हूं जो मैं गलत कर रहा हूं?

यहाँ HTML है:

<audio controls preload="auto">
    <source src="{{$coachingCall->getMp3Url()}}" type="audio/mpeg"/>
    <p>Your browser doesnt support embedded HTML5 audio. Here is a <a href="{{$coachingCall->getMp3Url()}}">link to the audio</a> instead.</p>
</audio>

एमपी 3 फ़ाइलों में टाइमस्टैम्प नहीं है, और इसलिए कोई अंतर्निहित लंबाई नहीं है जिसे समय से पहले जाना जा सकता है। क्रोम केवल अनुमान लगा रहा है, फ़ाइल की शुरुआत में बिटरेट और फ़ाइल के बाइट के आकार के आधार पर। यह वास्तव में पता नहीं है।

कुछ खिलाड़ी अनुमान लगाने से परेशान नहीं होते हैं।

इसके अलावा, आईओएस पर सभी ब्राउज़र ऐप्पल द्वारा कुछ अविश्वसनीय रूप से प्रतिबंधात्मक नीतियों के लिए धन्यवाद के तहत सफारी हैं। इसलिए, आईओएस पर क्रोम वास्तव में सफारी वेब दृश्य के लिए केवल एक आवरण है।





audio