因为公司需要开发移动APP,公司有没用android和IOS方面的技术人员,只有赶鸭子上架,自己上了,其他的就不说了主要使用的cordova,但是因为APP主要功能是播放视频,需要记录进度和禁止拖动进度条,然而自己对android了解不多只好选择HTML5来做视频播放。最后选择使用mediaelementjs

    首先要解决的是控制播放器禁止/允许进度条拖动,视频重看是允许拖动进度条的,否则不允许,改动mediaelementjs代码,重写播放器handleMouseMove事件,判断是否拖动。还有全屏问题,在android下全屏会带出系统自带的控制条,最后决定一开始就全屏,这里就需要获取屏幕宽度和高度,最好修改mediaelementjs 文件,出始化复制会影响用户体验。

$('video').mediaelementplayer({
        features: ['playpause','current','progress','duration','tracks'],//,'volume'音量控件
        success: function(media, node, player) {
            media.addEventListener("error", function(e) {
                var msg="出现未知错误";
            });
            media.addEventListener("timeupdate", function(e) {
                //这里是是播放器续播 为什么这样写下面说
                if(tempCurrentTime!=0){
                    media.setCurrentTime(tempCurrentTime);
                    if(media.currentTime == tempCurrentTime){
                        tempCurrentTime=0;
                    }
                } 
                 //进度条改变
            });
            media.addEventListener("playing", function(e) {
                //正在播放
            });
            media.addEventListener("pause", function(e) {
                //暂停播放
            });
            media.addEventListener("ended", function(e) {
                var msg="播放完成,即将关闭页面。";
            });
        }
    });

 

属性描述

audioTracks返回可用的音轨列表(MultipleTrackList对象)

autoplay媒体加载后自动播放

buffered返回缓冲部件的时间范围(TimeRanges对象)

controller返回当前的媒体控制器(MediaController对象)

controls显示播控控件

crossOriginCORS设置

currentSrc返回当前媒体的URL

currentTime当前播放的时间,单位秒

defaultMuted缺省是否静音

defaultPlaybackRate播控的缺省倍速

duration返回媒体的播放总时长,单位秒

ended返回当前播放是否结束标志

error返回当前播放的错误状态

initialTime返回初始播放的位置

loop是否循环播放

mediaGroup当前音视频所属媒体组 (用来链接多个音视频标签)

muted是否静音

networkState返回当前网络状态

paused是否暂停

playbackRate播放的倍速

played当前播放部件已经播放的时间范围(TimeRanges对象)

preload页面加载时是否同时加载音视频

readyState返回当前的准备状态

seekable返回当前可跳转部件的时间范围(TimeRanges对象)

seeking返回用户是否做了跳转操作

src当前音视频源的URL

startOffsetTime返回当前的时间偏移(Date对象)

textTracks返回可用的文本轨迹(TextTrackList对象)

videoTracks返回可用的视频轨迹(VideoTrackList对象)

volume音量值

事件描述

abort当音视频加载被异常终止时产生该事件

canplay当浏览器可以开始播放该音视频时产生该事件

canplaythrough当浏览器可以开始播放该音视频到结束而无需因缓冲而停止时产生该事件

durationchange当媒体的总时长改变时产生该事件

emptied当前播放列表为空时产生该事件

ended当前播放列表结束时产生该事件

error当加载媒体发生错误时产生该事件

loadeddata当加载媒体数据时产生该事件

loadedmetadata当收到总时长,分辨率和字轨等metadata时产生该事件

loadstart当开始查找媒体数据时产生该事件

pause当媒体暂停时产生该事件

play当媒体播放时产生该事件

playing当媒体从因缓冲而引起的暂停和停止恢复到播放时产生该事件

progress当获取到媒体数据时产生该事件

ratechange当播放倍数改变时产生该事件

seeked当用户完成跳转时产生该事件

seeking当用户正执行跳转时操作的时候产生该事件

stalled当试图获取媒体数据,但数据还不可用时产生该事件

suspend当获取不到数据时产生该事件

timeupdate当前播放位置发生改变时产生该事件

volumechange当前音量发生改变时产生该事件

waiting当视频因缓冲下一帧而停止时产生该事件

timeupdate赋值上次播放进度,之前有监听canplay和loadeddata事件赋值进度,但是在IOS7.0以下和android4.0以下的手机上,出现赋值失败,最后只能使用笨办法。

公司视频都是转格式为MP4,MP4文件都有一个metadata,只有当下载完metadata文件后才能开始播放,但是转码完不一定metadata就在视频文件最前面,所以有时会出现MP4加载好久才开始播放,这里需要用到MP4BOX工具处理一下MP4文件,处理完后metadata可以移动到最前端,也会相应的减小。

关于IOS下播放时出现自带控制器在标签里加入webkit-playsinline然后cordova配置文件中加入下列代码就能禁用IOS自带控制器

下面为IOS交互代码,主要实现MP4视频播放的屏幕横屏

- (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *urlString = [[request URL] absoluteString];
    NSArray *urlComps = [urlString componentsSeparatedByString:@"://"];
    if([urlComps count] && [[urlComps objectAtIndex:0] isEqualToString:@"objc"])
    {
        NSArray *arrFucnameAndParameter = [(NSString*)[urlComps objectAtIndex:1] componentsSeparatedByString:@"/"];
        NSString *funcStr = [arrFucnameAndParameter objectAtIndex:0];
        if (2 <= [arrFucnameAndParameter count])
        {
            // 有参数
            if([funcStr isEqualToString:@"openVideoPlayer"] && [arrFucnameAndParameter objectAtIndex:1])
            {
                /*调用本地函数*/
                NSLog(@"openVideoPlayer");
                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
                //view旋转
                [self.view setTransform:CGAffineTransformMakeRotation(M_PI/2)];
                self.view.frame = CGRectMake(0, 0, self.view.frame.size.height, self.view.frame.size.width);
                [[UIApplication sharedApplication] setStatusBarHidden:TRUE];
                [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"toVideoPlayer('%@');",[arrFucnameAndParameter objectAtIndex:1]]];
            }else if([funcStr isEqualToString:@"httpGet"] && [arrFucnameAndParameter objectAtIndex:1]){
                /*ios发送httpget请求*/
                NSURL *url=[NSURL URLWithString:[[arrFucnameAndParameter objectAtIndex:1] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
                NSURLRequest *request=[[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
                NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
                NSString *backData=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
                NSLog(@"backData:%@",backData);
                if ([arrFucnameAndParameter objectAtIndex:2]) {
                    [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@('%@','%@')",[arrFucnameAndParameter objectAtIndex:2],backData,[arrFucnameAndParameter objectAtIndex:3]]];
                }
            }
        }
        else if(1 == [arrFucnameAndParameter count])
        {
            //无参数的
            if([funcStr isEqualToString:@"closeVideoPlayer"])
            {
                /*关闭播放器,屏幕旋转回正*/
                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
                [self.view setTransform:CGAffineTransformIdentity];
                self.view.frame=CGRectMake(0, 0,self.view.frame.size.height, self.view.frame.size.width);
                [self.webView goBack];
                self.methodName = [[NSString alloc] initWithString:[NSString stringWithFormat:@"refreshCourse();"]];
            }else if ([funcStr isEqualToString:@"readSDCard"]){
                /*获取手机存储大小*/
                NSString *path=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
                NSFileManager *fileManager=[[NSFileManager alloc]init];
                NSDictionary *fileSysAttributes=[fileManager attributesOfFileSystemForPath:path error:nil];
                NSNumber *freeSpace=[fileSysAttributes objectForKey:NSFileSystemFreeSize];
                NSNumber *totalSpace=[fileSysAttributes objectForKey:NSFileSystemSize];
                NSString *result=[NSString stringWithFormat:@"%0.1f,%0.1f",[freeSpace longLongValue]/1024.0/1024.0/1024,[totalSpace longLongValue]/1024.0/1024.0/1024.0];
                NSLog(@"内存大小%@",result);
                [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setSdSize('%@')",result]];
            }
        }
    };
    return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
}

 

<preference name="AllowInlineMediaPlayback" value="true" />
<video id="courseplayer" type="video/mp4" width="100%" height="100%" controls="controls" preload="none" webkit-playsinline>

html5的video标签有一个弊端就是无法知道metadata文件加载了多少,也就是不知道还要多久才能播放