Android HTML5 视频 - 单击播放时有效,但 video.play() 无效

Posted

技术标签:

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

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

<video   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 我来晚了,但请在下面查看我的新答案... 【参考方案1】:

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

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

【讨论】:

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

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

<div id=content>
    <video   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>

【讨论】:

以上是关于Android HTML5 视频 - 单击播放时有效,但 video.play() 无效的主要内容,如果未能解决你的问题,请参考以下文章

在 Android HTML5 播放器中开始播放所需的用户手势

HTML5 视频不会在 Android 设备上循环播放

html5 视频中的单独播放/暂停按钮

使用 android 4 浏览器自动启动 html5 视频

HTML5在android WebView中没有视频只有音频播放

html5视频标签与Android全屏播放