Проблема Safari audio HTML5

#ios #networking #safari #html5-audio

#iOS #сетевой #сафари #html5-аудио

Вопрос:

Я работаю над проблемой iOS/macOS.

Я пытаюсь воспроизвести простой аудиофайл с помощью аудиоэлемента HTML5, и все работает так, как ожидалось, за исключением iOS/macOS.

Мое приложение построено на Symfony, используя Nginx и пользовательские контроллеры PHP для обслуживания аудиоресурса. Указанный источник аудиоэлемента является ссылкой на маршрут, который обрабатывает потоковую передачу.

Моя логика заключается в следующем :

  • Получить файл по идентификатору URL
  • Прочитайте заголовки запросов, чтобы найти ожидаемый диапазон и длину
  • Настройка хороших заголовков для принудительного 206 частичного поведения содержимого
  • Запись ожидаемых фрагментов файлов и возврат ответа 206.

Вот код для этого:

 public function getAudio(Request $request, $audioId)  {  /*  * Getting the file  */  $em = $this-gt;getDoctrine()-gt;getManager();  $voice = $em-gt;getRepository("CoreBundle:Audio")-gt;findOneById($audioId);  $media = $audio-gt;getFile();  $path = $this-gt;container-gt;get('sonata.media.twig.extension')-gt;path($media, 'reference');  $file = $this-gt;get('kernel')-gt;getRootDir() . "/../web$path";   /*  * Setting length and offset for serving the right chunk  */  $offset = 0;  $requestedRange = $request-gt;headers-gt;get("Range");  $size = $media-gt;getSize();  $length = $size;   if($requestedRange){  preg_match('/bytes=(d )-(d )?/', $requestedRange, $matches);  $offset = intval($matches[1]);  if(count($matches) gt; 2){  $length = intval($matches[2]) - $offset   1;  }  else{  $length = ($size) - $offset;  }  }   if(file_exists($file) amp;amp; $length) {  $file = fopen($file, 'r');  fseek($file, $offset);  $data = fread($file, $length);  fclose($file);   if($requestedRange){  header('Content-Range: bytes ' . $offset . '-' . ($offset   $length-1) . '/' . $size);  }  else{  header('Content-Range: bytes 0-'.($size-1).'/'.$size);  }    /*  * Forcing some headers in the response to fit request attempts  */  header("Pragma: public");  header("Expires: 0");  header('Content-type: audio/mpeg');  header('Content-Disposition: inline');  header('Accept-Ranges: bytes');  header('Content-Length: '.$length);  header('X-Pad: avoid browser bug');  header('Cache-Control: no-cache');    print($data);   return new Response("",206);  }  else{  return new Response("",200);  }  }  

Опять же, в Firefox и Chrome все работает нормально, файл передается в потоковом режиме и воспроизводится идеально. Но когда дело доходит до IOS и macOS, файл просто не воспроизводится. Беглый взгляд на сетевую консоль показывает два последующих запроса, последний из которых содержит ошибку (см. Следующие ссылки).

Однако в PHP не регистрируется никаких ошибок, и теперь я полностью застрял.

первый запрос

второй запрос

Ответ №1:

Логика была прекрасной, но управление ответом-нет.

Прочитав документацию по Symfony Response , я просто изменил все header() функции на:

 $response-gt;setHeaders()  

И каждый print($data) , чтобы:

 $response = new Response($data);  

Возврат полного Response объекта выполнил свою работу.