流式MP3:iOS在2分钟后重新启动HTML5音频 [英] Streaming MP3: iOS restarts HTML5 audio after 2 minutes

查看:80
本文介绍了流式MP3:iOS在2分钟后重新启动HTML5音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试流式传输mp3文件并通过HTML5音频标签播放.

I'm trying to stream an mp3 file and play it via HTML5 audio tag.

大约2分钟后,iOS从头开始播放音频.我在Safari @ iOS 11.4上进行了测试.

After about 2 minutes, iOS starts playing the audio from the start. I tested this on Safari @ iOS 11.4.

下面是简化代码:

文件:index.html

<!DOCTYPE html>
<html>
<body>
  <audio controls><source src="audio.php" type="audio/mpeg"></audio>
</body>
</html>

文件:audio.php

header('Content-Type: audio/mpeg');
header('Content-Disposition: inline; filename="audio.mp3"');
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');
readfile('audio.mp3');

  • 如果我直接使用audio.mp3文件,则音频有效
  • 一切都可以在所有其他设备/平台(Mac,Windows和Android上的所有浏览器)上正常运行.
    • Audio works if I use audio.mp3 file directly
    • Everything works well on all other devices / platforms (all browsers on Mac, Windows and Android).
    • 此设置有什么问题?
      如何正确地将音频流传输到iOS?

      What is wrong with this setup?
      How to properly stream audio to iOS?

      谢谢!

      推荐答案

      我遇到了同样的问题

      本文可帮助我解决问题

      https://mobiforge.com/design-development/content-delivery -mobile-devices

      问题出在某些必须在IOS上运行的标头参数上

      the problem is on some header parameters that must be set to work on IOS

      //insert file path
      $file = 'insert_file_path';
      
      //audio/mpeg for mp3 file
      $mime_type = 'audio/mpeg';
      
      if (is_file($file)) {
          header("Content-type: $mime_type");
          if (isset($_SERVER['HTTP_RANGE'])) { // do it for any device that supports byte-ranges not only iPhone
              rangeDownload($file);
          } else {
              header("Content-Length: " . filesize($file));
              readfile($file);
          }
      }else {
          // file not exist 
          // some error...
      }
      
      function rangeDownload($file) {
          $fp = @fopen($file, 'rb');
      
          $size   = filesize($file); // File size
          $length = $size;           // Content length
          $start  = 0;               // Start byte
          $end    = $size - 1;       // End byte
          // Now that we've gotten so far without errors we send the accept range header
          /* At the moment we only support single ranges.
           * Multiple ranges requires some more work to ensure it works correctly
           * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
           *
           * Multirange support annouces itself with:
           * header('Accept-Ranges: bytes');
           *
           * Multirange content must be sent with multipart/byteranges mediatype,
           * (mediatype = mimetype)
           * as well as a boundry header to indicate the various chunks of data.
           */
          header("Accept-Ranges: 0-$length");
          // header('Accept-Ranges: bytes');
          // multipart/byteranges
          // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
          if (isset($_SERVER['HTTP_RANGE'])) {
      
              $c_start = $start;
              $c_end   = $end;
              // Extract the range string
              list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
              // Make sure the client hasn't sent us a multibyte range
              if (strpos($range, ',') !== false) {
      
                  // (?) Shoud this be issued here, or should the first
                  // range be used? Or should the header be ignored and
                  // we output the whole content?
                  header('HTTP/1.1 416 Requested Range Not Satisfiable');
                  header("Content-Range: bytes $start-$end/$size");
                  // (?) Echo some info to the client?
                  exit;
              }
              // If the range starts with an '-' we start from the beginning
              // If not, we forward the file pointer
              // And make sure to get the end byte if spesified
              if ($range == '-') {
                  // The n-number of the last bytes is requested
                  $c_start = $size - substr($range, 1);
              }
              else {
                  $range  = explode('-', $range);
                  $c_start = $range[0];
                  $c_end   = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
              }
              /* Check the range and make sure it's treated according to the specs.
               * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
               */
              // End bytes can not be larger than $end.
              $c_end = ($c_end > $end) ? $end : $c_end;
              // Validate the requested range and return an error if it's not correct.
              if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
      
                  header('HTTP/1.1 416 Requested Range Not Satisfiable');
                  header("Content-Range: bytes $start-$end/$size");
                  // (?) Echo some info to the client?
                  exit;
              }
              $start  = $c_start;
              $end    = $c_end;
              $length = $end - $start + 1; // Calculate new content length
              fseek($fp, $start);
              header('HTTP/1.1 206 Partial Content');
          }
          // Notify the client the byte range we'll be outputting
          header("Content-Range: bytes $start-$end/$size");
          header("Content-Length: $length");
      
          // Start buffered download
          $buffer = 1024 * 8;
          while(!feof($fp) && ($p = ftell($fp)) <= $end) {
              if ($p + $buffer > $end) {
                  // In case we're only outputtin a chunk, make sure we don't
                  // read past the length
                  $buffer = $end - $p + 1;
              }
              set_time_limit(0); // Reset time limit for big files
              echo fread($fp, $buffer);
              flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
          }
          fclose($fp);
      }
      

      这篇关于流式MP3:iOS在2分钟后重新启动HTML5音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆