调用各种浏览器控件播放视频
本文所提及的所有范例都已添加或更新到新版 aardio 范例内,请到「范例 / Web 界面」目录下查看。
相关扩展库请更新到最新版,新版用起来更简洁更方便。
一、web.view ( WebView2 ) 播放视频。
WebView2 基于强悍的 Edge Chromium 内核,支持 HTML5 视频肯定是没问题,但 …… 这里面还是有些小坑要解决。
首先播放视频肯定是需要有全屏功能的,但是浏览器原生的 video 组件的全屏按钮 —— 实际上是不能全屏的,只能在网页内部最大化。浏览器可能认为随意全屏会对用户造成困扰。但毕竟看视频又确实需要全屏功能,所以浏览器又悄悄提供了真正请求全屏的函数 requestFullscreen()。不过浏览器原生播放器的全屏按钮属于 Shadow DOM 的隐藏节点 —— 并且浏览器会阻止获取这个节点,所以这个就麻烦了。自己实现这些控制按钮还是要费些功夫,于是我们打开万能的 GitHub 直接搜索 'video player' 看看有没有白嫖一个的可能性。
排名第一的是 video.js , 好吧我们凑个热闹就用他了。
先上代码:
import web.view;
import wsock.tcp.asynHttpServer;
import win.ui;
/*DSG{{*/var winform = win.form(text='WebView2(web.view) 播放视频并支持全屏';right=1008;bottom=616)/*}}*/
var httpServer = wsock.tcp.asynHttpServer();
httpServer.run( { ['/index.html'] = /**
<html>
<head>
<style type='text/css'> html,body { height: 100%; width: 100%; margin: 0;overflow: hidden; }</style>
<!--第一步:引入下面2个文件加载播放器 -->
<link href='https://cdn.jsdelivr.net/npm/video.js@7.15.4/dist/video-js.min.css' rel='stylesheet'>
<script src='">https://cdn.jsdelivr.net/npm/video.js@7.15.4/dist/video.min.js'></script></head>
<body>
<!-- 第二步:插入视频文件 --> <video id='my-player' class='video-js' controls preload='auto' poster='https://vjs.zencdn.net/v/oceans.png' style='width:100%;height:100%' data-setup='{}'> <source src='http://download.aardio.com/demo/video.aardio' type=' video/mp4'> </source> </video>
<script>
//第三步:修改播放器选项,这一步可以省略 videojs('my-player', { controlBar: { fullscreenToggle: true } });
//第四步:响应网页全屏请求
document.onfullscreenchange = function (event) { aardio.fullscreen(!!document.fullscreenElement); //调用 aardio 窗口的全屏函数 }
/* 注意原生 video 的全屏按钮只是网页内部最大化,不会触发 onfullscreenchange 事件。 vedio.js 播放器的全屏按钮则是调用视频节点的 requestFullscreen() 函数实现了真正的全屏。 */</script></body></html>**/;});
var wb = web.view( winform );
wb.external = { //浏览器仅仅是发出全屏指令,在这里用 aardio 控制全屏 fullscreen = lambda(fs) winform.fullscreen(fs) }wb.go( httpServer.getUrl('index.html') );
winform.show(); win.loopMessage();
这个范例在这里可以找到:
首先,为了避免不必要的麻烦,我们用 var httpServer = wsock.tcp.asynHttpServer() 创建一个 HTTP 服务器来给浏览器控件提供 HTML 文件,aardio 用几句代码就可以实现一个 HTTP 服务器,不会增加软件体积,不加白不加。现在很多前端的东西 —— 都针对 HTTP 服务器做了优化,并且对本地文件不友好(各种加限制),所以这是推荐的方式。
上面我们虚拟了一个 index.html 文件,如果你创建了 aardio 工程,这些 HTTP服务器默认就支持 aardio 工程里的资源目录下的路径,不用加任何代码,用起来更简单。
WebView2 组件收到网页代码的全屏请求以后会触发 document .onfullscreenchange 这个事件,并不会真的全屏。全屏还是挺复杂的,而且也超越了网页本该有的权限,人家只是一个浏览器控件,不是一个浏览器,所以全屏要我们自己实现。好在 aardio 的 winform 或 custom 控件都提供了全屏函数 fullscreen(),别看 aardio 体积小,好东西是真多。
我们先用下面的代码导出这个函数让网页中的 JavaScript 可以调用,这在 aardio 中就太简单了。
wb.external = { fullscreen = lambda(fs) winform.fullscreen(fs) }
然后在 JavaScript 中加上以下的关键代码:
document.onfullscreenchange = function (event) {
aardio.fullscreen(!!document.fullscreenElement); //调用 aardio 窗口的全屏函数
}
注意 document.fullscreenElement 是当前请求全屏的节点,如果这个属性不是 null 表示需要全屏,将这个属性用 !! 操作符转为布尔值刚好可以作为 winform.fullsreen() 函数的参数控制全屏或取消全屏。
二、web.form ( IE内核 ) 播放视频
很多人低估了 IE 内核的能力,IE的接口是非常强大的,而且属于系统自带的控件不占软件体积,现在 IE 11也已经普及。虽然比不上 WebView2 那么强大,新的前端技术支持 IE也不再热情,但你不要拿他跟浏览器比,你拿 IE 控件跟原生控件比,例如 static,picturebox…… 即然这些东西可以一直用,表现能力更强的 IE 控件我们也没理由嫌弃。不要跟专门做网页前端的去比较,大家目的不同。
另外虽然新的操作系统已经移除了 IE 浏览器,但 IE控件却作为操作系统不可分离的组件被保留。实际上依赖 IE 控件的桌面软件直到今日都拥有惊人的数量,这是很多人并没有意识到的。
我们知道 IE的最高版本 IE11,很多流行的前端组件都兼容 IE11,例如上面提到的 video.js 也兼容 IE11。虽然现在 IE11基本普及,但是考虑到还有少数没安装 IE11的系统,aardio 提供了一个库 web.form.ie11,使用这个库替代 web.form 会有一个好处:这个库会检测 IE11是否安装,如果没安装会自动升级到 IE11,。
我们前面的代码也可以在 web.form 里使用,但是有几个小细节要注意一下。IE 的全屏事件不是 fullscreenchange 而是 MSFullscreenChange, 而且一定要用 document.addEventListener() 来注册这个事件。注意网上有很多文章写成了 msfullscreenchange —— 实际上是不能用的。可用的 JavaScript 代码如下:
document.addEventListener('MSFullscreenChange', function () { external.fullscreen(!!document.msFullscreenElement)}, false);
上面可以看到,IE检测全屏节点的属性是 document.msFullscreenElement,这个名字跟 WebView2 也是不同的,要注意区分。
完整代码如下:
import win.ui;
/*DSG{{*/
var winform = win.form(text='WebView2(web.view) 播放视频并支持全屏';right=1008;bottom=616)
/*}}*/
import web.form.ie11;
var wb = web.form.ie11( winform );
//导出网页 JavaScript 可调用的 external 对象。
wb.external = {
//浏览器仅仅是发出全屏指令,在这里用 aardio 控制全屏
fullscreen = lambda(fs) winform.fullscreen(fs)
}
wb.html = /**
<html>
<head>
<style type='text/css'>
html,body { height: 100%; width: 100%; margin: 0;overflow: hidden; }
</style>
<!--第一步:引入下面2个文件加载播放器 -->
<link href='https://cdn.jsdelivr.net/npm/video.js@7.15.4/dist/video-js.min.css' rel='stylesheet'>
<script src='https://cdn.jsdelivr.net/npm/video.js@7.15.4/dist/video.min.js'></script>
</head>
<body>
<!-- 第二步:插入视频文件 -->
<video id='my-player' class='video-js' controls preload='auto' poster='https://vjs.zencdn.net/v/oceans.png'
style='width:100%;height:100%' data-setup='{}'>
<source src='http://download.aardio.com/demo/video.aardio' type=' video/mp4'>
</source>
</video>
<script>
//第三步:修改播放器选项,这一步可以省略
videojs('my-player', {
controlBar: {
fullscreenToggle: true
}
});
//第四步:响应网页全屏请求注意 MSFullscreenChange 大小写不能错
document.addEventListener('MSFullscreenChange', function () {
external.fullscreen(!!document.msFullscreenElement)
}, false);
</script>
</body></html>
**/
winform.show();
win.loopMessage();
aardio 范例中以下位置可以找到上面的代码:
三、web.kit ( WebKit 内核)播放视频
这是一个古老的精简版 WebKit ( WKE ), 也不要小看这个东西,放弃完美主义强迫症本着物尽其用的心态去看待他,有时候还是非常有用的。首先这个内核体积惊人的小,生成 EXE 如果打个压缩包就 3MB,而且还能支持古老的 Windows XP 系统 —— 当然现在要找到一个还在用 XP的是真有点难了。
今天我对 web.kit 做了一个重要的改进,可以更好地通过加载 aardio 扩展库为 web.kit 添加新的 NPAPI 插件,并且默认就可以生成独立EXE文件。
NPAPI 插件的一个用途就是用来加载 Flash 插件,其实现在还要非常多的 Flash 遗留程序,目前想重新运行他们并不容易,不过有了 web.kit 这事就不难了,写几句代码就可以让 Flash 完全复活,先来个播放 Flash 动画的小例子:
import win.ui;
/*DSG{{*/
var winform = win.form(text='Flash 动画';)
/*}}*/
import web.kit.form;
var wke = web.kit.form( winform );
import web.npPlugin.flash;
wke.html = /**
<embed quality=high bgcolor=#FFFFFF width='550'
height='400' id='flash' type='application/x-shockwave-flash'>
</embed>
<script>
loadSwf = function(url){
document.getElementById('flash').LoadMovie(0,url)
}
</script>
**/
wke.wait();
wke.script.loadSwf('https://update.aardio.com/v10.files/demo/transparent.swf')
winform.show()
win.loopMessage();
是不是简单又方便彻底完美解决问题?!
这个精简版的 WebKit 内核肯定是不支持 HTML5 视频了,但在 Flash 时代有一个强大的 html5media, 可以利用 Flash 插件实现兼容 HTML5 视频的效果,因为我们复活了 Flash ,所以就可以舒服地再次用上 html5media 了。
上代码:
import web.kit.form;
import web.npPlugin.flash;
import wsock.tcp.asynHttpServer;
import win.ui;
/*DSG{{*/
var winform = win.form(text='web.kit 支持 HTML5 视频(基于 Flash)';right=1008;bottom=616)
/*}}*/
var httpServer = wsock.tcp.asynHttpServer();
httpServer.run( {
['/index.html'] = /**
<html>
<head>
<style type='text/css'>
html,body { height:100%;width:100%;margin:0;overflow:hidden; }
</style>
<script src='https://cdn.jsdelivr.net/npm/html5media@1.2.1/dist/api/1.2.1/html5media.js'></script>
</head>
<body>
<video src='http://download.aardio.com/demo/video.aardio' width='100%' height='100%'
controls preload></video>
</body>
</html>
**/;
});
//通过HTTP服务器 Flash 才能访问网络,否则会有警告对话框。
//aardio 仅用数句代码就可以启动一个嵌入式HTTP服务器,不会增加软件体积。
var mb = web.kit.form( winform );
mb.go( httpServer.getUrl('index.html') );
winform.show();
win.loopMessage();
以上代码在范例中的位置:
要注意如果加载本地的 Flash ,默认是禁止访问网络的,会跳出一个体验非常差的警告。Flash 也是为了保护大全的安全操作了心 —— 结果把自己给操心没了。不过在 aardio 中解决这问题就太简单了,3句代码调用 wsock.tcp.asynHttpServer 创建一个嵌入 HTTP 服务器就搞定。
其实 Flash 真是挺强大的,虽然多少年前的东西,全屏这些都不用操心,代码也可以少写一些了。
四、web.blink( Miniblink 内核 )播放视频。
Miniblink 也是一个精简 Chromium 内核,兼容了前面说的 WebKit( WKE ) 的接口,体积要大一些,内核基于 Chromium 49。
Miniblink 同样不支持 HTML5视频,多年前试过支持 html5media ,但今天试了一下失败了,没任何反应,也没有报错。没有报错就只能全靠猜了,猜测 Miniblink 给出了误导的信息,一开始怀疑是 User-Agent,改了一下没起作用,然后用 JavaScript 测试了一下,Miniblink 在检测视频能力时默认会告知 JavaScript 他已经支持视频 —— 即然如此,于是 html5media 就什么也没干。
于是我把 html5media 下载过来,把检测的代码全删了。代码已经分享到 https://github.com/aardio/html5media-blink
然后我们把 html5media 的链接改成这个:https://cdn.jsdelivr.net/gh/aardio/html5media-blink@main/html5media.min.js
注意 jsdelivr.net 这个 CDN 在国内访问是非常快的,也很稳定,CDN 可以优先用这个( 程序打开的速度会快很多 ),而且 jsdelivr.net 支持 GitHub 和 NPM 上的文件,非常方便。
完整代码:
import web.blink.form;
import web.npPlugin.flash;
import wsock.tcp.asynHttpServer;
import win.ui;
/*DSG{{*/
var winform = win.form(text='web.blink 支持 HTML5 视频(基于 Flash)';right=1008;bottom=616)
winform.add()
/*}}*/
var httpServer = wsock.tcp.asynHttpServer();
httpServer.run( {
['/index.html'] = /**
<html>
<head>
<style type='text/css'>
html,body { height:100%;width:100%;margin:0;overflow:hidden;}
</style>
<script src='https://cdn.jsdelivr.net/gh/aardio/html5media-blink@main/html5media.min.js'></script>
</head>
<body>
<video src='http://download.aardio.com/demo/video.aardio' width='100%' height='100%' style='height: 100%; width: 100%'
controls preload></video>
</body>
</html>
**/;
});
//通过HTTP服务器 Flash 才能访问网络,否则会有警告对话框。
//aardio 仅用数句代码就可以启动一个嵌入式HTTP服务器,不会增加软件体积。
var mb = web.blink.form( winform );
mb.go( httpServer.getUrl('index.html') );
winform.show();
win.loopMessage();
aardio 中其他一些 Web 界面解决方案,例如 chrome.app 这些就是直接运行浏览器和网页,与网页开发没多大区别。更多的技巧大家可以继续探索。