【问题标题】:Android HTML5 video - works when clicking play, but not video.play()Android HTML5 视频 - 单击播放时有效,但 video.play() 无效
【发布时间】:2013-01-31 11:34:09
【问题描述】:

我了解 Android 上的 html5 视频无法自动播放。就目前而言,我的视频只有在用户点击播放按钮时才能在设备上播放。

<video width="640px" height="360px" src="media/video/Moments_of_Everyday_Life.mp4" controls id="video"></video>


<script type="text/javascript">
    $(function(){
        var video  = document.getElementById('video');
        video.play();
    });
</script>

不过,它可以在我的桌面上运行。

为什么这不起作用?还有点击播放和使用.play()有什么区别?

【问题讨论】:

  • 我很困惑。你是说这行得通,还是行不通?
  • 我说当你点击播放控制时它可以工作。但是使用调用 video.play() 不起作用。
  • 也就是说,手动播放视频作品。以编程方式播放它不会
  • @Harry 我来晚了,但请在下面查看我的新答案...

标签: android html html5-video


【解决方案1】:

由于浏览器阻止调用 window.open() 的原因相同,它不会起作用,因为允许它允许 Web 开发人员颠覆用户偏好而不是自动播放媒体(或打开弹出窗口)。

点击播放和使用这个方法的区别正是你所说的:点击。此类调用在点击事件中是允许的,但一般情况下是不允许的。

【讨论】:

  • 所以你的意思是视频无法自动播放? o 你有什么建议吗?
  • 您桌面上的浏览器是否阻止自动播放?您的浏览器是否存在开放缺陷like this one?我的建议是:不要让您的应用依赖自动播放(或等效的脚本),这不是您可以依赖的功能,因为浏览器将继续实施功能来阻止它。
  • 我终于搞定了!我想我会发布我的答案,因为网上大多数人都没有答案。现在让我们希望这对其他人有用
  • @Harry 你什么时候发布你的答案?
  • 这是正确的删节答案;我用下面的例子进行了修饰。从我这里点赞!
【解决方案2】:

我让它工作了!现在它可以播放带有“自动播放”功能的 HTML5 视频!该死的,这需要时间!好的,这就是我所做的:

<div id=content>
    <video width="1280px" height="720px" src="file:///android_asset/videos/Moments_of_Everyday_Life.mp4"></video>
</div>

注意:有些人说他们在添加海报和/或预加载时可以使用它。我得到了这个工作和没有。

Javascript 自动播放视频:

<script type="text/javascript">
    $(function(){
        function callback () {
            document.querySelector('video').src = document.querySelector('video').src
            document.querySelector('video').play();
        }
        window.addEventListener("load", callback, false);

    });
</script>

我希望这可以帮助任何人,我已经为此苦苦挣扎了一周!

要明确一点:

工作:

安卓 4.0.4 三星 10.1 平板电脑 原生设备浏览器

【讨论】:

  • 我使用了相同的代码。它不适用于安卓。我正在使用带有 phonegap 的 SAPUI5。
  • 老兄苦苦挣扎了 4 天,能否详细说明您的 HTML 和代码。请发帖
  • 我如何使用这个 javascript snip for android ?您可以编辑相同的答案吗?
  • 这不适用于我在 moto 4g plus 中的 android marshmallow。我挣扎了 2 天。解释更多
【解决方案3】:

经过数小时的搜索和测试“解决方案”,这对我有用!由Angry Fridges 解决(非常感谢)。

<video id="video" class="video" autoplay muted > 

注意到自动播放静音,它们都是必需的。

这允许视频在电脑和安卓手机上播放。

【讨论】:

    【解决方案4】:

    我在 kitkat 上发现 Firefox 将允许您以编程方式播放视频。

    此外,如果您进入 chrome://flags 并启用“禁用媒体播放的手势要求”选项,Chrome 也会这样做。

    【讨论】:

      【解决方案5】:

      我对 Android 4.0+ 上的 HTML5 视频有以下发现。

      为了执行这些测试,我制作了一个沙盒应用程序,其中包含一个保存在 /assets 中的 HTML 页面。

      HTML:

      <!DOCTYPE html>
      
      <html>
          <head>
              <title>HTML5 Video Test</title>
          </head>
      
          <body>
      
              <video preload="metadata"><source src="http://www.w3schools.com/html/movie.mp4" type="video/mp4"></video>
      
              <script> 
                var myvideo = document.getElementsByTagName('video')[0];
      
                myvideo.addEventListener('loadeddata', function() {
                  console.log("** RECEIVED loadeddata **");
                  myvideo.play();//this first play is needed for Android 4.1+
                }, false);
      
                myvideo.addEventListener('canplaythrough', function() {
                  console.log("** RECEIVED canplaythrough **");
                  myvideo.play();//this second play is needed for Android 4.0 only
                }, false);
      
              </script>
      
          </body>
      </html>
      

      JAVA: ("/assets/html5video.html")

      private WebView mWebView;
      private ProgressBar mProgressBar;
      
      @SuppressLint("NewApi")
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.videotest);
      
          // progress bar
          mProgressBar = (ProgressBar) findViewById(R.id.videotest_progressbar);
          mProgressBar.setProgress(0);
          mProgressBar.setVisibility(View.VISIBLE);
      
          // webview
          mWebView = (WebView) findViewById(R.id.videotest_webview);
          mWebView.getSettings().setJavaScriptEnabled(true);
      
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
          {
              //NOTE: this is required only for Android 4.2.2+
              mWebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
          }
      
          mWebView.setWebChromeClient(new WebChromeClient() {
              public void onProgressChanged(WebView view, int progress) {
                  Log.i(TAG, "Progress = "+progress);
                  mProgressBar.setProgress(progress);
              }
          });
          mWebView.setWebViewClient(new WebViewClient() {
              public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                  Toast.makeText(TestActivity.this, "Problem loading webpage", Toast.LENGTH_LONG).show();
                  mProgressBar.setVisibility(View.GONE);
              }
              public void onPageFinished(WebView view, String url) {
                  mProgressBar.setVisibility(View.GONE);
              }
          });
      }
      
      @Override
      protected void onResume() {
          super.onResume();
          mWebView.loadUrl("file:///android_asset/html5video.html");
      }
      

      Android 4.0.3 注意

      我一直遇到烦人的异常java.lang.Throwable: EventHub.removeMessages(int what = 107) is not supported before the WebViewCore is set up. 谢天谢地,它并没有影响视频播放。

      【讨论】:

      • 它适用于我尝试过的所有手机......直到一位同事给我带来了一台运行 Android 4.1.2 的 HTC One。相比之下,我拥有的三星 Note 2 也运行 Android 4.1.2 并且它会自动播放!我想指定“海报”属性是个好主意。
      【解决方案6】:

      或者你可以初始化你的 WebView 来轻松完成,如下:

      webview.setWebViewClient(new WebViewClient() {
          // autoplay when finished loading via javascript injection
          public void onPageFinished(WebView view, String url) { mMessageContentView.loadUrl("javascript:(function() { document.getElementsByTagName('video')[0].play(); })()"); }
      });
      

      以上对我来说很好。

      【讨论】:

        【解决方案7】:

        我在这里接受了一些建议,尤其是来自@JenniferG,但我仍然需要调整以获得良好的体验......这里是要点

        • 加载@JenniferG 提到的audio 标签
        • 使用适当的方法来访问 DOM 元素,对于 React,使用 refs
        • 取消静音,并在播放前设置音量
        • play() 方法返回一个承诺(at least in Chrome);使用catch 适当地处理错误
        • 注意不要在声音正在播放时调用play(),否则会失败
        • 用户必须与页面交互才能正常播放(请参阅下面的注释)

        注意:如果你没有让用户点击某个按钮,你会得到这样的错误

        play() 失败,因为用户没有先与文档交互。

        总而言之,这是一个示例 React 组件,它应该作为一个不错的起点(它是人为的,但应该说明可能性)

        class AudioPlayer extends React.Component
        {
            constructor(props) {
                super(props);
                this.audioRef = React.createRef();
                this.state = {
                    interacted: false,
                    firstSoundPlayed: false,
                    secondSoundPlayed: false,
                };
            }
        
            playAudio = () => {
                const node = this.audioRef.current;
                node.muted = false;
                node.volume = 1.0;
                node
                    .play()
                    .catch((e) => {
                        console.error('caught audio error: ', e.message);
                    });
            }
        
            handleClick = () => {
                this.setState({
                    interacted: true,
                });
                setTimeout(() => {
                    this.playAudio();
                    this.setState({
                        firstSoundPlayed: true,
                    });
                    setTimeout(() => {
                        this.playAudio();
                        this.setState({
                            secondSoundPlayed: true,
                        });
                    }, 6000);
                }, 4000);
            }
        
            renderStartup = () => (
                <p>
                    Please give me permission to play sounds...
                    <button onClick={this.handleClick}>Grant permission</button>
                </p>
            )
        
            renderScreen = () => (
                <div>
                    <p>I will play a sound as many times as I want now!</p>
                    <p>A sound is about to play...</p>
                </div>
            )
        
            renderSecondSound = () => (
                <div>
                    <p>Soon it will play again...</p>
                </div>
            )
        
            renderSummary = () => (
                <div>
                    <p>Hope you found this demo useful...</p>
                </div>
            )
        
            render = () => {
                const {
                    interacted,
                    firstSoundPlayed,
                    secondSoundPlayed,
                } = this.state;
        
                return (
                <div>
                    <audio
                        autoPlay
                        muted
                        src="https://freesound.org/data/previews/33/33245_65091-lq.mp3"
                        ref={this.audioRef}
                    />
                    {interacted === false ? this.renderStartup() : null}
                    {interacted === true && firstSoundPlayed === false ? this.renderScreen() : null}
                    {interacted === false || firstSoundPlayed === false || secondSoundPlayed === true ? null : this.renderSecondSound()}
                    {secondSoundPlayed === false ? null : this.renderSummary()}
                </div>);
            }
        }
        
        ReactDOM.render(
            <AudioPlayer />,
            document.getElementById('react')
        );
        <div id="react"></div>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.0/umd/react.production.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.0/umd/react-dom.production.min.js"></script>

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-10
          • 2014-04-06
          相关资源
          最近更新 更多