从 Chrome 文件系统播放视频不适用于 Android

Posted

技术标签:

【中文标题】从 Chrome 文件系统播放视频不适用于 Android【英文标题】:Playing Videos from Chrome Filesystem Not Working on Android 【发布时间】:2012-08-10 05:24:13 【问题描述】:

我正在尝试创建一个离线视频播放器,它可以从我的网站下载视频内容,以便以后通过 html5 视频元素离线观看。下面的代码在桌面版 Chrome 中运行良好,但在移动设备上却不行(Nexus S 智能手机、Nexus 7 平板电脑、4.1,因为只有运行 chrome,这是文件系统 api 所必需的)。我在桌面和移动设备上使用 chrome 支持的文件系统 API。

我已确认它已将文件正确存储在移动设备上,并且我可以正确检索文件,但由于某种原因,从本地系统 chrome 检索视频后不想播放视频。无论我是使用 html5 视频元素还是直接导航到文件系统 URL,这都是正确的。当我使用 html5 视频元素时,它返回错误 media_err_not_supported。我已经确认,如果我在我的服务器上直接导航到该设备(无需先使用文件系统 api 存储它),该设备可以播放视频,因此问题不是编解码器或视频格式问题。在这两种情况下,我也使用 video/mp4 mime 类型。

同样,这适用于桌面,但不适用于移动设备。有什么想法吗?

这是我们正在使用的代码:

<!DOCTYPE html >
<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"> </script>
        <script type="text/javascript">
            var _fs;
            var filename = "test3.mp4";
            var diskSpaceRequired = 10 * 1024 * 1024;
            $(document).ready(function () 
                window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
                function onInitFs(fs) 
                    _fs = fs;
                    getVideo(fs);
                

                if (!!window.requestFileSystem) 

                    window.webkitStorageInfo.requestQuota(
                        window.webkitStorageInfo.PERSISTENT,
                        diskSpaceRequired, // amount of bytes you need
                        function ()  ,
                        function () 
                    );
                    window.requestFileSystem(window.PERSISTENT, diskSpaceRequired, onInitFs, function ()  alert('error'); );
                 else 
                    alert('not supported');
                

                $("#play").on('click', playVideo);
                $("#ourVideo").on('error', function(e)  console.log('ERROR!!!', e, arguments);
                  console.log($("#ourVideo")[0].error);
                 );
            );

            function playVideo() 
               _fs.root.getFile(filename, , function (fileEntry) 
                    $("#ourVideo").attr('src', fileEntry.toURL());
                    fileEntry.file(function (file) 
                      var reader = new FileReader();
                      reader.onloadend = function (e) 
                        $("#ourVideo").get(0).play();
                      ;
                      reader.readAsText(file);
                    , errorHandler);

                , errorHandler);
            

            function getVideo(fs) 
                fs.root.getFile(filename,  create: true , function (fileEntry) 
                    fileEntry.createWriter(function (fileWriter) 
                        fetchResource(fileWriter);
                    , errorHandler);

                , errorHandler);
            

            function errorHandler(e) 
                console.log('error', e);
            

            function fetchResource(fileWriter) 
                console.log('fetchresource');
                var xhr = new XMLHttpRequest();
                xhr.responseType = "arraybuffer";
                xhr.open("GET", "http://mydomain.com/trailer.mp4", true);

                xhr.onload = function(e) 
                    if (this.status == 200) 
                        var bb = new WebKitBlobBuilder();
                        bb.append(this.response);

                        var blob = bb.getBlob("video\/mp4");
                        fileWriter.write(blob);
                     else  
                      console.log(this.status);
                    
                ;
                xhr.send();
                        

        </script>
        <title>foo</title>
    </head>
    <body>


        <input type="button" value="Play Video" id="play"/>
            <video id="ourVideo" controls="">
                <source id="vidSource"  type="video/mp4"/>
            </video>

    </body>
</html>

【问题讨论】:

文件下载后的完整路径是什么?您是否确实能够播放 那个 文件,而不是在别处单独下载的副本? 当在上面的代码中调用fileEntry.toURL()时,它会返回一个像这样的URL:filesystem:mydomain.com/persistent/test3.mp4。而且,是的,如果我直接导​​航到它正在下载的 URL(上面示例中的 mydomain.com/trailer.mp4),它可以正常播放视频。 看看能不能播放视频。将其从设备上取下并播放或从设备上的电影播放器​​播放。 内特,视频播放正常。根本问题是浏览器没有将 filesystem:foo.bar/video.mp4 转换为本地文件系统路径,因此 android 的播放器会在损坏的路径上出错。通过查看 Chromium 错误报告,我认为这已在 Chrome 20.0 中得到修复,但当前的 Android Chrome 仍停留在 18 版。 是的,视频播放良好,焦急地等待 Chrome 20.0 的发布。 :) 【参考方案1】:

问题看起来像您的 android chrome 无法正确访问 android 文件系统,为此您可以使用 nanoHttpd 服务器访问设备或 sdcard 中的 android 本地文件。 for NanoHttpd server 在您的应用程序中使用这一类并将媒体文件位置传递为http://localhost:8081/sdcard/(your_media_location).mp4

或者从https://gist.github.com/1893396获取nanoHttpd

我认为访问 sdcard 文件比直接调用它们更准确


尝试将html部分更改为

</head>
<body>


    <input type="button" value="Play Video" id="play"/>
        <video id="ourVideo" controls="">                
             <source src="video1.mp4" type= "video/mp4">
             <source src="video1.ogv" type= "video/ogg">
        </video>

</body>

您可以使用以下方法将您的 mp4 转换为 ogv http://video.online-convert.com/convert-to-ogg 并将ogv文件放在mp4中的相同位置

**欲了解更多信息,请查看这些 http://www.broken-links.com/2010/07/08/making-html5-video-work-on-android-phones/

HTML5 <video> element on Android does not play

【讨论】:

这是 HTML,不是原生应用程序。 “我正在尝试创建一个离线视频播放器”我认为这是一种 android 应用程序,顺便说一下,当我尝试使用没有的 android webview 时,你是否尝试使用 mp4 添加 ogv 格式没有 ogv 播放 mp4,我更新了我的答案 IIRC Android 支持 MP4 作为容器格式,但不支持所有 H.264 配置文件。我不记得 Ogg Vorbis 支持的状态是什么,现在是什么。 播放视频在这里不是问题 - 我们的视频可以正常播放,只要它们是流式传输的。它是从损坏的 HTML5 离线存储中播放的。

以上是关于从 Chrome 文件系统播放视频不适用于 Android的主要内容,如果未能解决你的问题,请参考以下文章

VideoJS 适用于 safari 但不适用于 chrome 中的某些带有 CORS 的视频

HTML5 视频自动播放不适用于 slick.js

Chrome 不自动播放静音视频

VideoJS 字体不适用于 Firefox 22 中的控件

HTML 5 自动播放 Google Chrome Android 未播放

HTML5 音频播放器适用于 safari/Chrome,但不适用于 iPhone