因为公司需要开发移动APP,公司有没用android和IOS方面的技术人员,只有赶鸭子上架,自己上了,其他的就不说了主要使用的cordova,但是因为APP主要功能是播放视频,需要记录进度和禁止拖动进度条,然而自己对android了解不多只好选择HTML5来做视频播放。最后选择使用mediaelementjs
地址:http://www.mediaelementjs.com/
首先要解决的是控制播放器禁止/允许进度条拖动,视频重看是允许拖动进度条的,否则不允许,改动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文件加载了多少,也就是不知道还要多久才能播放