Google chrome HTML5视频不会循环
我有一个视频作为网页的背景,我试图让它循环。代码如下:Google chrome HTML5视频不会循环,google-chrome,mime-types,html5-video,rack,gridfs,Google Chrome,Mime Types,Html5 Video,Rack,Gridfs,我有一个视频作为网页的背景,我试图让它循环。代码如下: <video autoplay='true' loop='true' muted='true'> <source src='/admin/wallpapers/linked/4ebc66e899727777b400003c' type='video/mp4'></source> </video> 即使我已经告诉视频循环,它没有。我还尝试让它使用onended属性进行循环(根据,我还尝
<video autoplay='true' loop='true' muted='true'>
<source src='/admin/wallpapers/linked/4ebc66e899727777b400003c' type='video/mp4'></source>
</video>
即使我已经告诉视频循环,它没有。我还尝试让它使用onended
属性进行循环(根据,我还尝试了jQuery)。到目前为止,一切都不起作用。这是Chrome的问题还是我的代码
编辑:
我检查了网络事件和一个工作副本()的头部与我正在尝试工作的应用程序。不同之处在于,工作拷贝是从Heroku上的静态资源(显然是通过Varnish)提供视频,而我的拷贝是从GridFS(MongoDB)提供的
Chrome Inspector的网络选项卡显示,在我的应用程序中,视频被请求了三次。一次状态为“待定”,第二次状态为“已取消”,最后一次状态为200 OK。工作副本仅显示两个请求,一个状态为挂起,另一个为部分内容。但是,在视频播放一次后,该请求变为“已取消”,并对该视频发出另一个请求。在我的应用程序中,这不会发生
至于类型,在我的应用程序中,两个是“未定义”,另一个是“video/mp4”(应该是这样)。在工作应用程序中,所有请求都是“视频/mp4”
此外,我将资源解释为其他资源,但传输时MIME类型未定义。
控制台中的警告
我真的不太确定从哪里开始。我认为问题是服务器端的,因为将文件作为静态资产来服务效果很好。可能是服务器没有发送正确的内容类型。这可能是GridFS的一个问题。我不知道
不管怎么说,源头是。非常感谢您提供的任何见解。看起来这在过去是一个问题,它至少有两个已关闭的bug,但都表示它已修复: 由于Chrome和Safari都使用基于webkit的浏览器,您可能可以使用以下一些解决方法:
啊,我正好碰到了这个问题 事实证明,Chrome上
元素的循环(或任何形式的搜索)只有在视频文件由理解部分内容请求的服务器提供时才有效。i、 e.服务器需要接受包含“范围”标头和206“部分内容”响应的请求。如果视频足够小,可以被chrome完全缓冲,并且不再进行服务器往返:如果您的服务器第一次没有满足chrome的范围请求,视频将无法循环或查看
是的,GridFS存在一个问题,尽管可以说Chrome应该更宽容一些。我的情况: 我有完全相同的问题,但是仅仅更改响应消息的标题并没有做到这一点。无循环、重放或寻道。此外,纯停止也不起作用,但这可能是我的配置 回答: 根据一些网站(再也找不到)的说法,在视频结束后,在下一个视频开始之前,也可能触发load()方法。这将重新加载源,导致视频/音频元素再次工作 @john 请注意,您的答案/链接是正常的bug,而不是关注此问题。使用服务器/Web服务器是导致此问题的原因。而这些链接描述的bug则是另一种。这也是答案不起作用的原因 我希望能有所帮助,我仍在寻找解决方案。最简单的解决方法:
$('video').on('ended', function () {
this.load();
this.play();
});
'end'
事件在视频结束时触发,video.load()
将视频重置为开始,并且video.play()
在加载后立即开始播放
这在Amazon S3上运行得很好,在Amazon S3中,您对服务器响应没有太多的控制权,而且还可以解决Firefox与视频相关的问题。如果视频缺少长度元数据,则currentTime
不可设置
没有jQuery的类似javascript:
document.getElementsByTagName('video')[0].onended = function () {
this.load();
this.play();
};
这是超级跛脚,但dropbox使用正确的状态代码。因此,上传到dropbox并用dl替换www
因此,使用dropbox url可以很好地播放视频。我知道这与所问的问题并不完全相关,但如果有人在遇到类似问题时遇到了这一点,请确保您的来源正确有序 我正在加载一个
mp4
和一个webm
文件,注意到视频没有在Chrome中循环。这是因为webm
文件是列出的第一个source
,所以Chrome正在加载webm
文件,而不是mp4
希望这能帮助其他遇到这个问题的人
<video autoplay loop>
<source src="/path-to-vid/video.mp4" type="video/mp4">
<source src="/path-to-vid/video.webm" type="video/webm">
</video>
如果上面的答案对您没有帮助,请确保在运行检查器时未选中禁用缓存选项。由于Chrome从缓存中获取视频,它基本上只工作一次。只是调试了20分钟才意识到这是原因。作为参考,所以我知道我不是唯一一个。我也有同样的问题,并且不可避免地通过流式传输内容来解决问题
e、 g这是PHP laravel blade html代码的代码,该代码请求流式传输路由:
<video>
<source src="{{route('getVideoStream',$videoId)}}" type="video/mp4"/>
</video>
VideoStream类是我从GitHub找到的流媒体类:
类视频流
{
private$path=“”;
私人$stream=“”;
私人$buffer=102400;
私有$start=-1;
私人$end=-1;
私人$size=0;
函数构造($filePath)
{
$this->path=$filePath;
}
/**
*明流
*/
私有函数open()
{
如果(!($this->stream=fopen($this->path,'rb')){
die('无法打开流进行读取');
}
}
/**
*设置合适的收割台,以便为视频服务
<video>
<source src="{{route('getVideoStream',$videoId)}}" type="video/mp4"/>
</video>
public function getVideoStream($videoId){
$path = $pathOfVideo;
$headers = [
'Content-Type' => 'video/mp2t',
'Content-Length' => File::size($path),
'Content-Disposition' => 'attachment; filename="start.mp4"'
];
$stream = new VideoStream($path);
return response()->stream(function () use ($stream) {
$stream->start();
});
}
class VideoStream
{
private $path = "";
private $stream = "";
private $buffer = 102400;
private $start = -1;
private $end = -1;
private $size = 0;
function __construct($filePath)
{
$this->path = $filePath;
}
/**
* Open stream
*/
private function open()
{
if (!($this->stream = fopen($this->path, 'rb'))) {
die('Could not open stream for reading');
}
}
/**
* Set proper header to serve the video content
*/
private function setHeader()
{
ob_get_clean();
header("Content-Type: video/mp4");
header("Cache-Control: max-age=2592000, public");
header("Expires: " . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT');
header("Last-Modified: " . gmdate('D, d M Y H:i:s', @filemtime($this->path)) . ' GMT');
$this->start = 0;
$this->size = filesize($this->path);
$this->end = $this->size - 1;
header("Accept-Ranges: 0-" . $this->end);
if (isset($_SERVER['HTTP_RANGE'])) {
$c_start = $this->start;
$c_end = $this->end;
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if (strpos($range, ',') !== false) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $this->start-$this->end/$this->size");
exit;
}
if ($range == '-') {
$c_start = $this->size - substr($range, 1);
} else {
$range = explode('-', $range);
$c_start = $range[0];
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end;
}
$c_end = ($c_end > $this->end) ? $this->end : $c_end;
if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $this->start-$this->end/$this->size");
exit;
}
$this->start = $c_start;
$this->end = $c_end;
$length = $this->end - $this->start + 1;
fseek($this->stream, $this->start);
header('HTTP/1.1 206 Partial Content');
header("Content-Length: " . $length);
header("Content-Range: bytes $this->start-$this->end/" . $this->size);
} else {
header("Content-Length: " . $this->size);
}
}
/**
* close curretly opened stream
*/
private function end()
{
fclose($this->stream);
exit;
}
/**
* perform the streaming of calculated range
*/
private function stream()
{
$i = $this->start;
set_time_limit(0);
while (!feof($this->stream) && $i <= $this->end) {
$bytesToRead = $this->buffer;
if (($i + $bytesToRead) > $this->end) {
$bytesToRead = $this->end - $i + 1;
}
$data = fread($this->stream, $bytesToRead);
echo $data;
flush();
$i += $bytesToRead;
}
}
/**
* Start streaming video content
*/
function start()
{
$this->open();
$this->setHeader();
$this->stream();
$this->end();
}
}