赞
踩
目录
腾讯云 Web 超级播放器 TCPlayer 可实现在手机浏览器和 PC 浏览器上播放音视频流的问题,功能强劲,兼容性好,可以不依赖用户安装 App,就能进行播放。
在实际的应用中,我们仍然根据需求直接改造了混淆代码,主要解决了以下问题:
1、增加、集成了播放快进组件
2、更改了一些样式
3、增强了一些旧版手机的兼容性
操作系统: Windows Server 2019 DataCenter
.net版本: .netFramework4.0 或以上
开发工具:VS2019 C#
浏览器需要支持 H5 技术。
(1)我们需要引入腾讯云 Web 超级播放器的 JS 库,以下是我改造后的资源,可点击如下链接进行下载:
https://download.csdn.net/download/michaelline/89367455
(2)前端布局,下载我的资源后,假设放在当前应用目录下,首先我们需要引入样式单,如下代码:
<link rel="stylesheet" href="tcplayer2021.css" />
其次,引入核心库,如下代码:
- <script type="text/javascript" src="hls.min.0.12.4.js"> </script>
- <script type="text/javascript" src="tcplayer.v4.min.js"> </script>
(3)需要引入 Jquery,以下是一组基于Jquery的自定义开发的扩展应用库,请下载我的资源:
https://download.csdn.net/download/michaelline/88615565
进行引用,本库用于调用服务器静态方法等功能使用。
播放器需要引入与结合 H5 的 Video 控件,假设有如下引用:
- <div id="coplayer" style="box-shadow:2px 0px 35px #000; -webkit-box-shadow:2px 0px 35px #000; background-color:rgb(69,69,69); position:fixed;top:40px;left:0px;width:80%;height:100px; margin: 0px auto;">
-
- <video id="realcoplayer" autoplay="autoplay" controls="controls" webkit-playsinline playsinline x5-playsinline x-webkit-airplay="allow" runat="server" ></video>
- <a id="b_rate" onclick="rate(this);" style=" float:right; line-height:25px; margin-right:10px; color:#fff;display:none;">1x</a>
-
- </div>
其中
1、coplayer 为外围容器层,控制一些样式和位置输出
2、realcoplayer 为 h5 video 控件,用于结合腾讯 web 超级播放器使用
其关键属性说明如下:
序号 | 属性与设置 | 说明 |
---|---|---|
1 | autoplay="autoplay" | 设置是否自动播放,在移动端或IOS系统可能无法实现 |
2 | controls="controls" | 是否显示控制工具栏,这里设置为需要显示 |
3 | webkit-playsinline playsinline | 兼容性属性:webkit-playsinline使ios 10中设置可以让视频在小窗内播放,即不全屏播放。 playsinline 可使用IOS/微信浏览器支持小窗内播放 |
4 | x5-playsinline | H5 移动是否禁用全屏,这里为允许,为空则不允许 |
5 | x-webkit-airplay="allow" | 使此视频支持ios的AirPlay(隔空播放)功能,隔空播放能将各种 Apple 设备中的音乐流传输到家中的多个扬声器上,并让这些扬声器中播放的旋律始终保持合拍, 让音乐荡漾在每个房间。 |
3、b_rate 为用于改造及引入超级播放器的快进组件,配合其使用。
客户端播放器的初始化代码如下:
- var player = new TCPlayer('realcoplayer', {
- fileID: 111,
- appID: '125407',
- playbackRates: [0.5, 1, 1.25, 1.5, 2],
- autoplay: false,
- live: false,
- x5_player: true,
- volume: 0.5,
- flash: true,
- x5_player: true,
- systemFullscreen: false,
- playsinline: true,
- x5_orientation: 0,
- x5_type: 'h5',
- allowFullScreen: false,
- width:_w,
- height:_h,
-
- });
在实际使用中,为保证良好的可用性和兼容性,还需要设置如下属性,说明见下表:
序号 | 参数 | 类型 | 说明 |
---|---|---|---|
1 | fileID | string | 云点播平台可播放视频文件的 fileID |
2 | appID | string | 云点播平台申请的 appID |
3 | playbackRates | float[] | 快进倍速设置,如此数组 [0.5, 1, 1.25, 1.5, 2] |
4 | autoplay | bool | 是否设置为自动播放,false 为不自动 |
5 | live | bool | 是否直播功能,默认为 false |
6 | x5_player | bool | 设为 true 。是否启用 TBS 的播放 flv 或 hls 。启用时播放器将在 TBS 模式下(例如 Android 的微信、QQ 浏览器),将 flv 或 hls 播放地址直接赋给 <video> 播放。 |
7 | volume | float | 默认音量,0-1,0.5为居中 |
8 | flash | bool | 一个兼容的重要属性,设为 true |
9 | systemFullscreen | bool | 开启后(true),在不支持 Fullscreen API 的浏览器环境下,尝试使用浏览器提供的 webkitEnterFullScreen 方法进行全屏,如果支持,将进入系统全屏,控件为系统控件 |
10 | playsinline | bool | 兼容性属性,设为 true |
11 | x5_orientation | int | 通过 video 属性 “x5-video-orientation” 声明 TBS 播放器支持的方向,可选值: 0:landscape 横屏 1:portraint 竖屏 2:landscape | portrait 跟随手机自动旋转。 (备注:该属性为 TBS 内核实验性属性,非 TBS 内核不支持) |
12 | x5_type | string | 通过 video 属性 “x5-video-player-type” 声明启用同层 H5 播放器,支持的值:h5-page (该属性为 TBS 内核实验性属性,非 TBS 内核不支持) |
13 | allowFullScreen | bool | 兼容性写法,是否允许全屏播放 |
14 | width | int | 设置播放器宽度,单位为像素。 |
15 | height | int | 设置播放器高度,单位为像素。 |
通过跟踪超级播放器提供的监听事件,实现我们的开发需求,其关键事件说明如下:
序号 | 事件 | 说明 |
---|---|---|
1 | timeupdate | 播放时间更新事件,可记录播放时间,其结构体如下: player.on('timeupdate',function(){ }) |
2 | play | 开始播放时事件,其结构体如下: player.on('play',function(){ }) |
3 | fullscreenchange | 切换全屏状态事件,其结构体如下: player.on('fullscreenchange',function(){ }) |
4 | seeked | 拖动播放进度结束事件,其结构体如下: player.on('seeked',function(){ }) |
5 | pause | 播放暂停时事件,其结构体如下: player.on('pause',function(){ }) |
6 | ended | 播放结束时事件,其结构体如下: player.on('ended',function(){ }) |
7 | canplay | 播放能力执行成功事件,其结构体如下: player.on('canplay',function(){ }) |
8 | loadeddata | 音视频数据加载完毕时事件,其结构体如下: player.on('loadeddata',function(){ }) |
9 | ratechange | 改变快进倍速完成时事件,其结构体如下: player.on('ratechange',function(){ }) |
类实现代码如下:
- public class QR_LIMIT_STR_SCENE
- {
- public string AccessToken { get; set; }
- public string ticket { get; set; }
- public string url { get; set; }
- public string ResultJson = "";
- public QR_LIMIT_STR_SCENE()
- {
- }
- public string getUrl(string scene_str)
- {
- string PostJson = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"" + scene_str + "\"}}}";
- String action = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + AccessToken;
- WebService ws = new WebService();
- string rs = ws.GetResponseResult(action, Encoding.UTF8, "POST", PostJson);
- Newtonsoft.Json.Linq.JObject jsonObj = Newtonsoft.Json.Linq.JObject.Parse(rs);
- ticket = jsonObj["ticket"] != null ? jsonObj["ticket"].ToString() : "";
- url = jsonObj["url"] != null ? jsonObj["url"].ToString() : "";
- ResultJson = rs;
- return "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket;
-
- }
- }
编写浏览器是否支持终端H5播放的判断,实现代码如下:
- function checkVideo() {
- if (!!document.createElement('video').canPlayType) {
- var vidTest = document.createElement("video");
- oggTest = vidTest.canPlayType('video/ogg; codecs="theora, vorbis"');
- if (!oggTest) {
- h264Test = vidTest.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
- if (!h264Test) {
- return false;
- }
- else {
- if (h264Test == "probably") {
- return true;
- }
- else {
- return false;
- }
- }
- }
- else {
- if (oggTest == "probably") {
- return true;
- }
- else {
- return false;
- }
- }
- }
- else {
- return false;
- }
- return true;
- }
- if (!checkVideo()) {
- alert('您的浏览器不支持Video播放,请使用支持H5技术的浏览器!');
- }
在某些华为手机我们发现倍速快进组件样式显示异常,因此引入 JS 函数,对机型增加了一些判断 ,代码如下:
- function judgeBrand(sUserAgent) {
- var isIphone = sUserAgent.match(/iphone/i) == "iphone";
- var isHuawei = sUserAgent.match(/huawei/i) == "huawei";
- var isHonor = sUserAgent.match(/honor/i) == "honor";
- var isOppo = sUserAgent.match(/oppo/i) == "oppo";
- var isOppoR15 = sUserAgent.match(/pacm00/i) == "pacm00";
- var isVivo = sUserAgent.match(/vivo/i) == "vivo";
- var isXiaomi = sUserAgent.match(/mi\s/i) == "mi ";
- var isXiaomi2s = sUserAgent.match(/mix\s/i) == "mix ";
- var isRedmi = sUserAgent.match(/redmi/i) == "redmi";
- var isSamsung = sUserAgent.match(/sm-/i) == "sm-";
-
- if (isIphone) {
- return 'iphone';
- } else if (isHuawei || isHonor) {
- return 'huawei';
- } else if (isOppo || isOppoR15) {
- return 'oppo';
- } else if (isVivo) {
- return 'vivo';
- } else if (isXiaomi || isRedmi || isXiaomi2s) {
- return 'xiaomi';
- } else if (isSamsung) {
- return 'samsung';
- } else {
- return 'default';
- }
- }
对华为手机的判断处理代码如下:
- if(judgeBrand(navigator.userAgent.toLowerCase())=='huawei'){
- $("#b_rate").html="1x";
- $("#b_rate").css("display","");
- }else{
- $("#b_rate").css("display","none");
- }
相对完整的实现代码(包括样式引入、前端控件和JS控制)如下:
- <link rel="stylesheet" href="tcplayer2021.css" />
- <asp:TextBox ID="x_roomid" checkSchema="" runat="server" style="display:none"></asp:TextBox>
- <script type="text/javascript" src="hls.min.0.12.4.js"> </script>
- <script type="text/javascript" src="tcplayer.v4.min.js"> </script>
- <script type="text/javascript" language="javascript" src="jquery.js" ></script>
-
- <div id="h5panel" runat="server" >
- <asp:TextBox ID="x_fileid" style="display:none;" runat="server"></asp:TextBox>
- <asp:TextBox ID="current" Text="0" style="display:none;" runat="server"></asp:TextBox>
- <asp:TextBox ID="duration" Text="0" style="display:none;" runat="server"></asp:TextBox>
- <asp:TextBox ID="mname" style="display:none;" runat="server"></asp:TextBox>
- <asp:TextBox ID="x_mp4url" style="display:none;" runat="server"></asp:TextBox>
- <asp:TextBox ID="x_CoverUrl" style="display:none;" runat="server"></asp:TextBox>
- <asp:TextBox ID="x_playMark" style="display:none;" runat="server"></asp:TextBox>
- <asp:TextBox ID="x_lasttime" style="display:none;" runat="server"></asp:TextBox>
- <asp:TextBox ID="confirmflag" Text="0" runat="server" style="display:none;" ></asp:TextBox>
- <asp:TextBox ID="playMarkflag" Text="0" runat="server" style="display:none;" ></asp:TextBox>
- <asp:TextBox ID="x_videocount" Text="0" style="display:none;" runat="server"></asp:TextBox>
-
- <div id="coplayer" style="box-shadow:2px 0px 35px #000; -webkit-box-shadow:2px 0px 35px #000; background-color:rgb(69,69,69); position:fixed;top:40px;left:0px;width:80%;height:100px; margin: 0px auto;">
- <video id="realcoplayer" autoplay="autoplay" controls="controls" webkit-playsinline playsinline x5-playsinline x-webkit-airplay="allow" runat="server" ></video>
- <a id="b_rate" onclick="rate(this);" style=" float:right; line-height:25px; margin-right:10px; color:#fff;display:none;">1x</a>
- </div>
-
- <script language="javascript">
- var windowheight=$(window).height();
- form = document.forms[0];
-
- function checkVideo() {
- if (!!document.createElement('video').canPlayType) {
- var vidTest = document.createElement("video");
- oggTest = vidTest.canPlayType('video/ogg; codecs="theora, vorbis"');
- if (!oggTest) {
- h264Test = vidTest.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
- if (!h264Test) {
- return false;
- }
- else {
- if (h264Test == "probably") {
- return true;
- }
- else {
- return false;
- }
- }
- }
- else {
- if (oggTest == "probably") {
- return true;
- }
- else {
- return false;
- }
- }
- }
- else {
- return false;
- }
- return true;
- }
- if (!checkVideo()) {
- alert('您的浏览器不支持Video播放,请使用支持H5技术的浏览器!');
- }
-
- var timer=null;
- var curtime=0;
- function stimer(){
- timer=window.setInterval("setpmark()",1000);
- }
- function etimer(){
- window.clearInterval(timer);
- }
-
- function secondToDate(result) {
- var h = Math.floor(result / 3600) < 10 ? '0'+Math.floor(result / 3600) : Math.floor(result / 3600);
- var m = Math.floor((result / 60 % 60)) < 10 ? '0' + Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60));
- var s = Math.floor((result % 60)) < 10 ? '0' + Math.floor((result % 60)) : Math.floor((result % 60));
- if(h=="00"){
- return result = m + ":" + s;
- }else{
- return result = h + ":" + m + ":" + s;
- }
- }
- var _w = $(document).width();
- if(_w>=1200){
- _w=640;
- }
- _h=_w/16*9;
-
- function resizeAll(){
- var _w = $(document).width();
- if(_w>=1200){
- _w=640;
- }
- _h=_w/16*9;
- if(player.isFullscreen()==true){
- }
- document.getElementById('coplayer').style.left=($(document).width()-_w)/2+'px';
- document.getElementById('coplayer').style.width=_w+'px';
- document.getElementById('coplayer').style.height=_h+'px';
-
- function aiplaymark(curtime){
- player.currentTime(curtime);
- player.play();
- }
-
- var debug=document.getElementById('debug');
- var curtime=0;
- var seeked=false;
-
- var player = new TCPlayer('realcoplayer', { fileID: document.getElementById('x_fileid').value, appID: '12540',
- playbackRates: [0.5, 1, 1.25, 1.5, 2],
- autoplay: false,
- live: false,
- x5_player: true,
- volume: 0.5,
- flash: true,
- x5_player: true,
- systemFullscreen: false,
- playsinline: true,
- x5_orientation: 0,
- x5_type: 'h5',
- allowFullScreen: false,
- width:_w,
- height:_h,
-
- });
-
- player.on('timeupdate',function(){
- document.getElementById("current").value=player.currentTime();
- })
- player.on('play',function(){
- stimer();
- updcountinfo('play',0);
- })
- player.on('fullscreenchange',function(){
- })
-
- player.on('seeked',function(){
- })
- player.on('pause',function(){
- etimer();
- })
- player.on('ended',function(){
- etimer();
- })
- player.on('canplay',function(){
- })
- player.on('loadeddata',function(){
- player.poster(document.getElementById('x_CoverUrl').value);
- if(judgeBrand(navigator.userAgent.toLowerCase())=='huawei'){
- $("#b_rate").html="1x";
- $("#b_rate").css("display","");
- }else{
- $("#b_rate").css("display","none");
- }
- this.currentTime(document.getElementById("current").value);
- })
-
- player.on('ratechange',function(){
- $('#b_rate').html($('.vjs-playback-rate-value').html());
- })
- function rate(o) {
- document.querySelectorAll('.vjs-playback-rate')[1].click();
- }
-
- function judgeBrand(sUserAgent) {
- var isIphone = sUserAgent.match(/iphone/i) == "iphone";
- var isHuawei = sUserAgent.match(/huawei/i) == "huawei";
- var isHonor = sUserAgent.match(/honor/i) == "honor";
- var isOppo = sUserAgent.match(/oppo/i) == "oppo";
- var isOppoR15 = sUserAgent.match(/pacm00/i) == "pacm00";
- var isVivo = sUserAgent.match(/vivo/i) == "vivo";
- var isXiaomi = sUserAgent.match(/mi\s/i) == "mi ";
- var isXiaomi2s = sUserAgent.match(/mix\s/i) == "mix ";
- var isRedmi = sUserAgent.match(/redmi/i) == "redmi";
- var isSamsung = sUserAgent.match(/sm-/i) == "sm-";
-
- if (isIphone) {
- return 'iphone';
- } else if (isHuawei || isHonor) {
- return 'huawei';
- } else if (isOppo || isOppoR15) {
- return 'oppo';
- } else if (isVivo) {
- return 'vivo';
- } else if (isXiaomi || isRedmi || isXiaomi2s) {
- return 'xiaomi';
- } else if (isSamsung) {
- return 'samsung';
- } else {
- return 'default';
- }
- }
- function updcountinfo(ctype,counts){
- if(ctype=='play'){
- if(document.getElementById('x_videocount').value=='0'){
- document.getElementById('x_videocount').value='1';
- }else{
- return;
- }
- }
- callServerFunction("", "updateCountInfo","{cid:'"+$("#x_cid").val()+"',ctype:'"+ctype+"',counts:'"+counts+"'}", sscount);
- }
-
- function setpmark(){
- curtime++;
- callServerFunction("", "updatePersonLearnInfo","{cid:'"+$("#x_cid").val()+"',uid:'"+$("#x_uid").val()+"',pid:'"+$("#x_pid").val()+"',playmark:'"+$('#current').val()+"',steptime:'1'}", ss);
- }
-
- var sTime;
-
- </script>
(1)关于更多的超级播放器 SDK 开发介绍,请参照如下链接:
https://cloud.tencent.com/document/product/881/30818
(2)实现代码中事件代码仅供参考,对于服务器静态方法实现需要根据我们实际的应用需求进行开发。
(3)实现代码中的前端控件,只为演示实例使用,可根据需要改造符合自己的开发规范。
感谢您的阅读,希望本文能够对您有所帮助。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。