gpt4 book ai didi

ios - Mac 和 IOS 14 上的 Safari 无法播放 HTML 5 MP4 视频

转载 作者:行者123 更新时间:2023-12-04 23:20:54 34 4
gpt4 key购买 nike

所以我开发了一个使用 Node 作为后端的聊天应用程序。当用户在他们的 iphone 上选择一个视频时,它通常是 .mov 格式,因此当它被发送到 Node 服务器时,它会使用 ffmpeg 转换为 mp4。一切正常,然后如果我在我的 Mac 上的 Chrome 中再次加载我的聊天,视频播放就像 mp4 一样好。
enter image description here
此屏幕截图显示视频嵌入在那里,设置为 mp4 但它不会在我的 mac 或手机上的 Safari 中播放,实际上它只是将视频显示为 0 秒长但我可以在 chrome 中播放它并下载 mp4通过直接访问嵌入 url 文件。
有任何想法吗?我将其转换为 mp4 以防止此类事情发生,但 safari 似乎甚至不喜欢 mp4 文件。
提供私有(private)文件​​的后端部分在 Symfony 4 (PHP) 中:

/**
* @Route("/private/files/download/{base64Path}", name="downloadFile")
* @param string $base64Path
* @param Request $request
* @return Response
*/
public function downloadFile(string $base64Path, Request $request) : Response
{


// get token
if(!$token = $request->query->get('token')){
return new Response('Access Denied',403);
}



/** @var UserRepository $userRepo */
$userRepo = $this->getDoctrine()->getRepository(User::class);

/** @var User $user */
if(!$user = $userRepo->findOneBy(['deleted'=>false,'active'=>true,'systemUser'=>false,'apiKey'=>$token])){
return new Response('Access Denied',403);
}



// get path
if($path = base64_decode($base64Path)){

// make sure the folder we need exists
$fullPath = $this->getParameter('private_upload_folder') . '/' . $path;



if(!file_exists($fullPath)){
return new Response('File Not Found',404);
}



$response = new Response();
$response->headers->set('Content-Type', mime_content_type($fullPath));
$response->headers->set('Content-Disposition', 'inline; filename="' . basename($fullPath) . '"');
$response->headers->set('Content-Length', filesize($fullPath));
$response->headers->set('Pragma', "no-cache");
$response->headers->set('Expires', "0");
$response->headers->set('Content-Transfer-Encoding', "binary");

$response->sendHeaders();

$response->setContent(readfile($fullPath));

return $response;
}

return new Response('Invalid Path',404);
}
尝试嵌入视频时,除了 Safari 外,这在任何地方都可以正常工作。这样做是因为视频不是公开的并且需要访问 token 。
更新:这是一个 mp4 的测试链接,您必须允许不安全的证书,因为它位于快速测试子域上。如果你在 chrome 中打开它,你会看到我的 3d 打印机固化站的 3 秒视频,如果你在 safari 中加载相同的链接,你会发现它不起作用
https://tester.nibbrstaging.com/private/files/download/Y2hhdC83Nzk1Y2U2MC04MDFmLTExZWItYjkzYy1lZjI4ZGYwMDhkOTMubXA0?token=6ab1720bfe922d44208c25f655d61032
服务器在带有 Apache 的 cPanel 上运行,我认为这可能与需要流式传输的视频有关?
可在 Safari 中运行但现在在 Chrome 中损坏的更新代码:
Chrome 现在提供 Content-Length: 0 但它在 safari 中运行良好。
public function downloadFile(string $base64Path, Request $request) : ?Response
{

ob_clean();

// get token
if(!$token = $request->query->get('token')){
return new Response('Access Denied',403);
}




/** @var UserRepository $userRepo */
$userRepo = $this->getDoctrine()->getRepository(User::class);

/** @var User $user */
if(!$user = $userRepo->findOneBy(['deleted'=>false,'active'=>true,'systemUser'=>false,'apiKey'=>$token])){
return new Response('Access Denied',403);
}



// get path
if($path = base64_decode($base64Path)){

// make sure the folder we need exists
$fullPath = $this->getParameter('private_upload_folder') . '/' . $path;



if(!file_exists($fullPath)){
return new Response('File Not Found',404);
}


$filesize = filesize($fullPath);
$mime = mime_content_type($fullPath);

header('Content-Type: ' . $mime);

if(isset($_SERVER['HTTP_RANGE'])){

// Parse the range header to get the byte offset
$ranges = array_map(
'intval', // Parse the parts into integer
explode(
'-', // The range separator
substr($_SERVER['HTTP_RANGE'], 6) // Skip the `bytes=` part of the header
)
);



// If the last range param is empty, it means the EOF (End of File)
if(!$ranges[1]){
$ranges[1] = $filesize - 1;
}

header('HTTP/1.1 206 Partial Content');
header('Accept-Ranges: bytes');
header('Content-Length: ' . ($ranges[1] - $ranges[0])); // The size of the range

// Send the ranges we offered
header(
sprintf(
'Content-Range: bytes %d-%d/%d', // The header format
$ranges[0], // The start range
$ranges[1], // The end range
$filesize // Total size of the file
)
);

// It's time to output the file
$f = fopen($fullPath, 'rb'); // Open the file in binary mode
$chunkSize = 8192; // The size of each chunk to output

// Seek to the requested start range
fseek($f, $ranges[0]);

// Start outputting the data
while(true){
// Check if we have outputted all the data requested
if(ftell($f) >= $ranges[1]){
break;
}

// Output the data
echo fread($f, $chunkSize);

// Flush the buffer immediately
@ob_flush();
flush();
}
}else{

// It's not a range request, output the file anyway
header('Content-Length: ' . $filesize);

// Read the file
@readfile($filesize);

// and flush the buffer
@ob_flush();
flush();



}

}else {

return new Response('Invalid Path', 404);
}
}
我在 chrome 中注意到它正在发送这样的范围 header :
范围:字节=611609-
Safari 发送的地方
范围:字节=611609-61160
因此,由于某种原因,chrome 缺少第二个范围数量,这显然意味着我的代码找不到第二个的范围编号。
不管我做什么,我都无法让它在 chrome 和 safari 中运行。 Safari 想要字节范围部分,chrome 似乎请求它然后发送一个完整文件的新请求,但即使是代码的完整文件部分也会给出 500 错误。如果我取出字节范围位,那么它在 chrome 中可以正常工作,但不能在 safari 中正常工作。
更新:
这是chrome中发生的一些奇怪的事情:
对于我正在测试的视频,它提出了 3 个范围请求:
REQUEST 1 HEADERS - 请求字节 0-(到文件末尾)
GET /private/files/download/Y2hhdC83Nzk1Y2U2MC04MDFmLTExZWItYjkzYy1lZjI4ZGYwMDhkOTMubXA0?token=6ab1720bfe922d44208c25f655d61032 HTTP/1.1

Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36
Accept-Encoding: identity;q=1, *;q=0
Accept: */*
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: video
Referer: https://gofollow.vip/
Accept-Language: en-US,en;q=0.9
Range: bytes=0-
RESPONSE 将文件中的所有字节返回给它,因为这就是 Chrome 所要求的:
HTTP/1.1 206 Partial Content
Date: Wed, 10 Mar 2021 12:35:54 GMT
Server: Apache
Accept-Ranges: bytes
Content-Length: 611609
Content-Range: bytes 0-611609/611610
Vary: User-Agent
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: video/mp4
第二个请求 header :现在它要求 589824 到文件末尾:
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36
Accept-Encoding: identity;q=1, *;q=0
Accept: */*
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: video
Referer: https://gofollow.vip/
Accept-Language: en-US,en;q=0.9
Range: bytes=589824-
响应义务:
HTTP/1.1 206 Partial Content
Date: Wed, 10 Mar 2021 12:35:55 GMT
Server: Apache
Accept-Ranges: bytes
Content-Length: 21785
Content-Range: bytes 589824-611609/611610
Vary: User-Agent
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: video/mp4
然后它发出了导致内部服务器错误的第三个请求,这一次它实际上是在请求最后一个字节:
GET /private/files/download/Y2hhdC83Nzk1Y2U2MC04MDFmLTExZWItYjkzYy1lZjI4ZGYwMDhkOTMubXA0?token=6ab1720bfe922d44208c25f655d61032 HTTP/1.1

Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36
Accept-Encoding: identity;q=1, *;q=0
Accept: */*
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: video
Referer: https://gofollow.vip/
Accept-Language: en-US,en;q=0.9
Range: bytes=611609-
响应 - 内容长度为 0,因为请求的字节和返回的字节之间没有差异:
HTTP/1.1 500 Internal Server Error
Date: Wed, 10 Mar 2021 12:35:56 GMT
Server: Apache
Accept-Ranges: bytes
Cache-Control: max-age=0, must-revalidate, private
X-Frame-Options: DENY
X-XSS-Protection: 1
X-Content-Type-Options: nosniff
Referrer-Policy: origin
Strict-Transport-Security: max-age=31536000; includeSubDomains
Expires: Wed, 10 Mar 2021 12:35:56 GMT
Content-Length: 0
Content-Range: bytes 611609-611609/611610
Vary: User-Agent
Connection: close
Content-Type: text/html; charset=UTF-8

最佳答案

毕竟我终于找到了问题。它要求第三个请求中的最后一个字节和以下代码来计算发回内容的大小:

header('Content-Length: ' . ($ranges[1] - $ranges[0])); // The size of the range
将长度作为最后一个字节生成为 0,直到文件末尾为 0。所以我将其更改为加 1 到最后:
header('Content-Length: ' . (($ranges[1] - $ranges[0])+1)); // The size of the range
我以为我可能对此有疑问,但事实证明它适用于两种浏览器

关于ios - Mac 和 IOS 14 上的 Safari 无法播放 HTML 5 MP4 视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66532319/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com