热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在androidwebview的全屏上播放HTML5视频。-PlayingHTML5videoonfullscreeninandroidwebview

Well,Ivebeensearchingfewdaysalready,howtodisplayHTML5videoinfull-screenmodeonandroi

Well, I've been searching few days already, how to display HTML5 video in full-screen mode on android WebView.

好吧,我已经搜索了几天了,如何在android WebView的全屏模式下显示HTML5视频。

I managed to play HTML5 videos on my webview. Problems are arising when displaying video in fullscreen mode.

我设法在我的webview上播放HTML5的视频。在全屏模式显示视频时出现问题。

As I figured out, android has two ways of handling the

正如我所指出的,android有两种方式来处理 <视频> 标签:

  1. On android versions <= 2.3.3, the onShowCustomView method is fired, and I can have the VideoView instance, and set listeners when the video completes, set controllers etc. So far so good.

    在android版本的<= 2.3.3中,onShowCustomView方法被触发,我可以有视频视图实例,在视频完成时设置监听器,设置控制器等等。

  2. On ICS (and probably 3.0 and above), it looks like the

    在ICS(可能是3.0或以上)上,它看起来像 <视频> ,以不同的方式处理。当HTML5视频播放onShowCustomView不是被称为正常模式——它看起来像有一个内部业务WebView中播放视频,和所有的控件中定义的 <视频> 标记所示——我不能以任何方式访问它。实际上,如果视频在正常模式下播放,这是可以的,因为控制在那里并且正在工作。

That led me to the big problem: when displaying the video in full screen mode the onShowCustomView is being called - but on ICS the "view" parameter isn't an instance of VideoView.

这让我想到了一个大问题:当在全屏模式下显示视频时,onShowCustomView正在被调用,但在ICS上,“view”参数并不是VideoView的实例。

I managed to find out that the instance is of VideoSurfaceView, a private inner class of HTML5VideoFullScreen class. The only way we can access this inner-class is via reflection.

我设法找到了VideoSurfaceView的实例,它是HTML5VideoFullScreen类的一个私有内部类。我们可以通过反射来访问这个内部类。

After looking at GrepCode for this class, I learnt that unlike VideoView, the HTML5VideoFullScreen$VideoSurfaceView doesn't hold a MediaPlayer instance that I can listen to its events or access its controls. The only thing I can do is take this VideoSurfaceView as it is and put it inside a full-screen-layout without controlling it.

在查看了这个类的GrepCode之后,我了解到,与VideoView不同的是,HTML5VideoFullScreen$VideoSurfaceView不包含一个MediaPlayer实例,我可以侦听它的事件或访问它的控件。我能做的唯一一件事就是把这个VideoSurfaceView放到一个全屏幕布局中而不去控制它。

Bottom line - When displaying video in full-screen, I don't know when the video ends, its controls aren't shown - this is pretty sad. I can't get the trigger for closing the full-screen.

底线——当在全屏显示视频时,我不知道视频什么时候结束,它的控制没有显示出来——这是相当可悲的。我无法得到关闭全屏的触发器。

I tried few unsuccessful workarounds:

我尝试了几个不成功的方法:

  1. Reflection: I tried to reach the HTML5VideoFullScreen instance, which holds a MediaPlayer member, from the inner-class VideoSurfaceView. I didn't manage to get it, I'm not sure this is possible (ViewSurfaceView doesn't hold its owner's instance).

    反射:我试着访问了HTML5VideoFullScreen实例,它包含一个MediaPlayer成员,来自于内部类VideoSurfaceView。我没有得到它,我不确定这是可能的(ViewSurfaceView不保存它的所有者的实例)。

  2. Register for the video events via Javascript (onended, for example), and handle what I need back in JAVA via JavascriptInterface: I found this solution isn't reliable because while doing this I encountered another problem: the

    通过Javascript(例如onend)注册视频事件,并通过JavascriptInterface处理我在JAVA中需要的东西:我发现这个解决方案不可靠,因为在做这个过程时,我遇到了另一个问题:

I'm still searching for a solution, very little is written about this issue. Did anyone manage to solve it? Help would be much appreciated!

我还在寻找解决方案,关于这个问题的文章很少。有人能解决吗?非常感谢您的帮助!

VideoView class: Here (has MediaPlayer)

VideoView类:这里(有MediaPlayer)

HTML5VideoFullScreen$VideoSurfaceView class: Here (doesn't have MediaPlayer)

HTML5VideoFullScreen$VideoSurfaceView类:这里(没有MediaPlayer)

7 个解决方案

#1


157  

Edit 2014/10: by popular demand I'm maintaining and moving this to GitHub. Please check cprcrack/VideoEnabledWebView for the last version. Will keep this answer only for reference.

Edit 2014/01: improved example usage to include the nonVideoLayout, videoLayout, and videoLoading views, for those users requesting more example code for better understading.

编辑2014/01:改进的示例用法包括非视频播放、视频播放和视频播放视图,这些用户请求更多的示例代码,以便更好地理解。

Edit 2013/12: some bug fixes related to Sony Xperia devices compatibility, but which in fact affected all devices.

编辑2013/12:一些与索尼Xperia设备兼容性相关的bug修复,但实际上影响了所有设备。

Edit 2013/11: after the release of Android 4.4 KitKat (API level 19) with its new Chromium webview, I had to work hard again. Several improvements were made. You should update to this new version. I release this source under WTFPL. Donations are accepted (find Donate link at bottom).

编辑2013/11:Android 4.4 KitKat (API level 19)发布后,我不得不再次努力工作。了一些改进。您应该更新到这个新版本。我在WTFPL下释放这个源。捐赠被接受(在底部发现捐赠链接)。

Edit 2013/04: after 1 week of hard work, I finally have achieved everything I needed. I think this two generic classes that I have created can solve all you problems.

编辑2013/04:经过一周的辛苦工作,我终于实现了我所需要的一切。我认为我创建的这两个通用类可以解决您所有的问题。

VideoEnabledWebChromeClient can be used alone if you do not require the functionality that VideoEnabledWebView adds. But VideoEnabledWebView must always rely on a VideoEnabledWebChromeClient. Please read all the comments of the both classes carefully.

如果你不需要VideoEnabledWebView添加的功能,VideoEnabledWebChromeClient可以单独使用。但VideoEnabledWebView必须始终依赖于VideoEnabledWebChromeClient。请仔细阅读这两门课的所有评论。

VideoEnabledWebChromeClient class

import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.webkit.WebChromeClient;
import android.widget.FrameLayout;

/**
 * This class serves as a WebChromeClient to be set to a WebView, allowing it to play video.
 * Video will play differently depending on target API level (in-line, fullscreen, or both).
 *
 * It has been tested with the following video classes:
 * - android.widget.VideoView (typically API level <11)
 * - android.webkit.HTML5VideoFullScreen$VideoSurfaceView/VideoTextureView (typically API level 11-18)
 * - com.android.org.chromium.content.browser.ContentVideoView$VideoSurfaceView (typically API level 19+)
 * 
 * Important notes:
 * - For API level 11+, android:hardwareAccelerated="true" must be set in the application manifest.
 * - The invoking activity must call VideoEnabledWebChromeClient's onBackPressed() inside of its own onBackPressed().
 * - Tested in Android API levels 8-19. Only tested on http://m.youtube.com.
 *
 * @author Cristian Perez (http://cpr.name)
 *
 */
public class VideoEnabledWebChromeClient extends WebChromeClient implements OnPreparedListener, OnCompletionListener, OnErrorListener
{
    public interface ToggledFullscreenCallback
    {
        public void toggledFullscreen(boolean fullscreen);
    }

    private View activityNonVideoView;
    private ViewGroup activityVideoView;
    private View loadingView;
    private VideoEnabledWebView webView;

    private boolean isVideoFullscreen; // Indicates if the video is being displayed using a custom view (typically full-screen)
    private FrameLayout videoViewContainer;
    private CustomViewCallback videoViewCallback;

    private ToggledFullscreenCallback toggledFullscreenCallback;

    /**
     * Never use this constructor alone.
     * This constructor allows this class to be defined as an inline inner class in which the user can override methods
     */
    @SuppressWarnings("unused")
    public VideoEnabledWebChromeClient()
    {
    }

    /**
     * Builds a video enabled WebChromeClient.
     * @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.
     * @param activityVideoView A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.
     */
    @SuppressWarnings("unused")
    public VideoEnabledWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView)
    {
        this.activityNOnVideoView= activityNonVideoView;
        this.activityVideoView = activityVideoView;
        this.loadingView = null;
        this.webView = null;
        this.isVideoFullscreen = false;
    }

    /**
     * Builds a video enabled WebChromeClient.
     * @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.
     * @param activityVideoView A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.
     * @param loadingView A View to be shown while the video is loading (typically only used in API level <11). Must be already inflated and without a parent view.
     */
    @SuppressWarnings("unused")
    public VideoEnabledWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView, View loadingView)
    {
        this.activityNOnVideoView= activityNonVideoView;
        this.activityVideoView = activityVideoView;
        this.loadingView = loadingView;
        this.webView = null;
        this.isVideoFullscreen = false;
    }

    /**
     * Builds a video enabled WebChromeClient.
     * @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.
     * @param activityVideoView A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.
     * @param loadingView A View to be shown while the video is loading (typically only used in API level <11). Must be already inflated and without a parent view.
     * @param webView The owner VideoEnabledWebView. Passing it will enable the VideoEnabledWebChromeClient to detect the HTML5 video ended event and exit full-screen.
     * Note: The web page must only contain one video tag in order for the HTML5 video ended event to work. This could be improved if needed (see Javascript code).
     */
    public VideoEnabledWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView, View loadingView, VideoEnabledWebView webView)
    {
        this.activityNOnVideoView= activityNonVideoView;
        this.activityVideoView = activityVideoView;
        this.loadingView = loadingView;
        this.webView = webView;
        this.isVideoFullscreen = false;
    }

    /**
     * Indicates if the video is being displayed using a custom view (typically full-screen)
     * @return true it the video is being displayed using a custom view (typically full-screen)
     */
    public boolean isVideoFullscreen()
    {
        return isVideoFullscreen;
    }

    /**
     * Set a callback that will be fired when the video starts or finishes displaying using a custom view (typically full-screen)
     * @param callback A VideoEnabledWebChromeClient.ToggledFullscreenCallback callback
     */
    public void setOnToggledFullscreen(ToggledFullscreenCallback callback)
    {
        this.toggledFullscreenCallback = callback;
    }

    @Override
    public void onShowCustomView(View view, CustomViewCallback callback)
    {
        if (view instanceof FrameLayout)
        {
            // A video wants to be shown
            FrameLayout frameLayout = (FrameLayout) view;
            View focusedChild = frameLayout.getFocusedChild();

            // Save video related variables
            this.isVideoFullscreen = true;
            this.videoViewCOntainer= frameLayout;
            this.videoViewCallback = callback;

            // Hide the non-video view, add the video view, and show it
            activityNonVideoView.setVisibility(View.INVISIBLE);
            activityVideoView.addView(videoViewContainer, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
            activityVideoView.setVisibility(View.VISIBLE);

            if (focusedChild instanceof android.widget.VideoView)
            {
                // android.widget.VideoView (typically API level <11)
                android.widget.VideoView videoView = (android.widget.VideoView) focusedChild;

                // Handle all the required events
                videoView.setOnPreparedListener(this);
                videoView.setOnCompletionListener(this);        
推荐阅读
  • 安卓开发入门!BAT大厂面试基础题集合,顺利通过阿里Android岗面试
    其实不是Android不行了,而是你跟不上了我的很多读者都在反馈说,现在一个岗位可以收到的简历数,是前几年的几倍。我们必须承认ÿ ... [详细]
  • Thisworkcameoutofthediscussioninhttps://github.com/typesafehub/config/issues/272 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 实现一个通讯录系统,可添加、删除、修改、查找、显示、清空、排序通讯录信息
    本文介绍了如何实现一个通讯录系统,该系统可以实现添加、删除、修改、查找、显示、清空、排序通讯录信息的功能。通过定义结构体LINK和PEOPLE来存储通讯录信息,使用相关函数来实现各项功能。详细介绍了每个功能的实现方法。 ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
  • 本文介绍了Foundation框架中一些常用的结构体和类,包括表示范围作用的NSRange结构体的创建方式,处理几何图形的数据类型NSPoint和NSSize,以及由点和大小复合而成的矩形数据类型NSRect。同时还介绍了创建这些数据类型的方法,以及字符串类NSString的使用方法。 ... [详细]
  • [转载]从零开始学习OpenGL ES之四 – 光效
    继续我们的iPhoneOpenGLES之旅,我们将讨论光效。目前,我们没有加入任何光效。幸运的是,OpenGL在没有设置光效的情况下仍然可 ... [详细]
  • QuestionThereareatotalofncoursesyouhavetotake,labeledfrom0ton-1.Somecoursesmayhaveprerequi ... [详细]
  • 用户视图(查看运行状态或其他参数)系统视图(配置设备的系统参数)system-viewEntersystemview,returnuservi ... [详细]
  • 资源:吊炸天!74款APP完整源码!android界面中点击输入框时弹出输入法如果输入框在底部会出现输入法遮挡输入内容的问题解决办法设置activity的windowsoftinpu ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了预加载多个本地WebView相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
moses_945_5e245a
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有