Html 谷歌浏览器不会在移动设备上自动播放 HTML5 视频

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39892713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 13:54:01  来源:igfitidea点击:

Google Chrome does not autoplay HTML5 video on mobile

htmlgoogle-chromevideo

提问by Martin Braun

I have problems to get a video to play on my Android mobile in the latest version of Chrome. In other browsers like the Puffin browser the video is playing. For test purposes I tried all common formats:

我在最新版本的 Chrome 中无法在我的 Android 手机上播放视频。在其他浏览器(如海雀浏览器)中,视频正在播放。出于测试目的,我尝试了所有常见格式:

mp4
<br />
<video autoplay="autoplay" loop="loop" onended="this.play()"><source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type="video/mp4" /></video>
<br />
webm
<br />
<video autoplay="autoplay" loop="loop" onended="this.play()"><source src="http://clips.vorwaerts-gmbh.de/VfE.webm" type="video/webm" /></video>
<br />
ogg
<br />
<video autoplay="autoplay" loop="loop" onended="this.play()"><source src="http://clips.vorwaerts-gmbh.de/VfE.ogv" type="video/ogg" /></video>

https://codepen.io/anon/pen/ozpVNP

https://codepen.io/anon/pen/ozpVNP

QR Code for CodePen

CodePen 二维码

Preview on mobile

在手机上预览

According to Mozillathe first video, that is H.264 + AAC in MP4 should play. I also take this articlein account and tried to play the videos by JavaScript additionally as well as tried to remove the typeattribute on the first videotag without success.

根据Mozilla的第一个视频,即 MP4 中的 H.264 + AAC 应该可以播放。我也考虑到这篇文章,并尝试通过 JavaScript 额外播放视频,并尝试删除type第一个video标签上的属性,但没有成功。

How can I get it work in Chrome on Mobile?

如何让它在移动版 Chrome 中运行?

采纳答案by Jaco

The problem is that Google want that users initiate by themselves any media, so If you debug your device chrome browser, you will get the warning "Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture." So that means you need to attach the video initialization, for example, with a click event

问题是谷歌希望用户自己启动任何媒体,所以如果你调试你的设备 chrome 浏览器,你会收到警告“无法在 'HTMLMediaElement' 上执行'播放':API 只能由用户手势启动。" 所以这意味着您需要附加视频初始化,例如,使用单击事件

回答by Кристина Александрова

<video autoplay loop autobuffer muted playsinline>
     <source src="video/video-hat.mp4" type="video/mp4">
</video>

回答by racitup

There doesn't appear to be any great info on this, so thought I'd post my findings.

似乎没有任何关于此的重要信息,所以我想我会发布我的发现。

I've been debugging html5 video playback on Chrome desktop and mobile on an Android 5.0.1 Samsung S4 with Chrome 61 and the embedded browser, and Safari 9 & 11, using an automatic javascript play/pause written in AngularJS (below). The video is embedded in a carousel so is sometimes visible, sometimes not. In summary:

我一直在使用 AngularJS 编写的自动 javascript 播放/暂停(如下)在带有 Chrome 61 和嵌入式浏览器的 Android 5.0.1 三星 S4 和 Safari 9 和 11 上调试 Chrome 桌面和移动设备上的 html5 视频播放。视频嵌入在轮播中,因此有时可见,有时不可见。总之:

  • I would recommend having both webm(vp8/vorbis) and mp4(h264/aac) formats. These are the most supported formats and have equivalent quality for the same bitrate. ffmpeg can encode both.
  • It seems Chrome mobile prefers webm if it can get it, so put that first.
  • If a browser plays a file when you direct it to the file url, this does notmean it will play it when embedded in a video tag, though it will tell you if the format & codecs are supported if it does play. Chrome mobile seems very picky about having a video source whose resolution is too high.
  • Safari (and probably iOS) will notplay a video unless served by a server supporting byte-ranges. Apache, nginx and Amazon S3 for example do support them, but many smaller web servers (like WSGI servers) do not.
  • The order of the videos matters more than the source mediaattribute. Always have low resolution versions of a video first. The example below uses 1920x1080 and 1280x720. It seems if the mobile browser encounters a video that is "too high-res", it just stops processing the other sources and prefers the poster.
  • having a controlsattribute and manual play vs playing through javascript doesn't appear to make any difference.
  • the mutedattribute stops android from putting a little speaker icon in the status bar when playing but off-screen, even when the video doesn't have audio. As a side-note, I'd also really think about your audience if you intend to autoplay video with sound. Personally I think it's a bad idea.
  • the preloadattribute doesn't seem to make much difference. The browser will tend to automatically preload the selected video metadata anyway.
  • having a source typeattribute does not stop the video from playing. If anything it helps the browser choose which source to pick for the best
  • the JS video.oncanplayevent is the best way to see if the video tag has been successful. If you don't get that, the video won't play, but the browser won't tell you why.
  • 我建议同时使用 webm(vp8/vorbis) 和 mp4(h264/aac) 格式。这些是最受支持的格式,并且对于相同的比特率具有相同的质量。ffmpeg 可以对两者进行编码。
  • 如果可以的话,Chrome mobile 似乎更喜欢 webm,所以把它放在第一位。
  • 如果浏览器在您将文件定向到文件 url 时播放文件,这并不意味着它会在嵌入视频标签时播放它,尽管它会告诉您如果播放时是否支持格式和编解码器。Chrome 移动版似乎对分辨率太高的视频源非常挑剔。
  • 除非由支持字节范围的服务器提供服务,否则Safari(可能还有 iOS)不会播放视频。例如,Apache、nginx 和 Amazon S3 确实支持它们,但许多较小的 Web 服务器(如 WSGI 服务器)不支持。
  • 视频的顺序比源media属性更重要。始终首先拥有视频的低分辨率版本。下面的示例使用 1920x1080 和 1280x720。似乎如果移动浏览器遇到“太高分辨率”的视频,它只会停止处理其他来源并更喜欢海报。
  • 具有controls属性和手动播放与通过 javascript 播放似乎没有任何区别。
  • muted属性阻止 android 在播放但屏幕外时在状态栏中放置一个小扬声器图标,即使视频没有音频。作为旁注,如果您打算自动播放带声音的视频,我也会真正考虑您的观众。我个人认为这是一个坏主意。
  • preload属性似乎没有太大区别。无论如何,浏览器都会倾向于自动预加载选定的视频元数据。
  • 具有源type属性不会阻止视频播放。如果有的话,它可以帮助浏览器选择最好的来源
  • JSvideo.oncanplay事件是查看视频标签是否成功的最佳方式。如果你不明白,视频就不会播放,但浏览器不会告诉你原因。

HTML:

HTML:

<video class="img-responsive-upscale ng-scope"
  video-auto-ctrl loop muted preload poster="0022.png">
  <source src="vid_small.webm" media="(max-width: 1280px)" type="video/webm">
  <source src="vid_small.mp4" media="(max-width: 1280px)" type="video/mp4">
  <source src="vid.webm" media="(max-width: 1920px)" type="video/webm">
  <source src="vid.mp4" type="video/mp4">
  <img src="0022.png" alt="something"
    title="Your browser does not support the <video> tag">
</video>

Javascript:

Javascript:

<script type="text/javascript">
angular.module('myproducts.videoplay', []).directive('videoAutoCtrl',
  function() {
  return {
    require: '^uibCarousel',
    link: function(scope, element, attrs) {
      var video = element[0];
      var canplay = false;
      var rs = ["HAVE_NOTHING", "HAVE_METADATA", "HAVE_CURRENT_DATA", "HAVE_FUTURE_DATA", "HAVE_ENOUGH_DATA"];
      var ns = ["NETWORK_EMPTY", "NETWORK_IDLE", "NETWORK_LOADING", "NETWORK_NO_SOURCE"];

      function vinfo() {
        console.log("currentSrc = " + video.currentSrc);
        console.log("readyState = " + rs[video.readyState]);
        console.log("networkState = " + ns[video.networkState]);
        bufinfo();
      }

      function bufinfo() {
        // tr is a TimeRanges object
        tr = video.buffered
        if (tr.length > 0) {
          var ranges = ""
          for (i = 0; i < tr.length; i++) {
            s = tr.start(i);
            e = tr.end(i);
            ranges += s + '-' + e;
            if (i + 1 < tr.length) {
              ranges += ', '
            }
          }
          console.log("buffered time ranges: " + ranges);
        }
      }

      video.onerror = function () {
        console.log(video.error);
      }

      video.oncanplay = function () {
        canplay = true;
        if (!playing) {
          console.log("canplay!");
          vinfo();
        }
      }

      var playing = false;
      function playfulfilled(v) {
        console.log("visible so playing " + video.currentSrc.split('/').pop());
        playing = true;
      }

      function playrejected(v) {
        console.log("play failed", v);
      }

      function setstate(visible) {
        if (canplay) {
          if (visible) {
            p = video.play();
            if (p !== undefined) {
              p.then(playfulfilled, playrejected);
            }
          } else if (playing) {
            video.pause();
            console.log("invisible so paused");
            playing = false;
          }
        } else {
          console.log("!canplay, visible:", visible);
          vinfo();
        }
      }
      // Because $watch calls $parse on the 1st arg, the property doesn't need to exist on first load
      scope.$parent.$watch('active', setstate);
    }
  };
});
</script>

回答by An Le

I had an issue where the video worked on my desktop chrome, and desktop-mobile view, but not my iphone. Turns out i needed to add the "playsinline" property to the video tag. :]

我有一个问题,视频在我的桌面 chrome 和桌面移动视图上工作,但在我的 iphone 上不起作用。结果我需要将“playsinline”属性添加到视频标签中。:]

回答by Harinarayanan Nagarajan

The issue fixed for me after switching off "Data saving" mode in chrome.

在 chrome 中关闭“数据保存”模式后,我解决了这个问题。