当前位置:网站首页>H5 makes its own video player (JS Part 2)
H5 makes its own video player (JS Part 2)
2020-11-06 01:17:00 【:::::::】
review
Forget it. No review
Start directly , open JS1 Written in bvd.js
Play the video
- Play button hidden
- The video starts playing When you click the play button , The play button will be hidden , Play the video , This is not hard to , stay JS1 We've already achieved . But let's change our thinking , Add a click to the video tap event , Make the video play , Then trigger the playback event , So that the play button is hidden pro.initEvent = function(){ var that = this; // Add events to the play button image this.vimg.addEventListener('tap',function(){ that.video.play(); }) // Video Click to pause or play events this.video.addEventListener('tap',function(){ if(this.paused || this.ended) { // When you pause, click to play if(this.ended) {// If it's over , It starts all over again this.currentTime = 0; } this.play(); } else { // Click to pause while playing this.pause(); } }) // Video playback Events this.video.addEventListener('play',function(){ that.vimg.style.display = 'none'; }) // Get metadata this.video.addEventListener('loadedmetadata',function(){ that.vC.querySelector('.duration').innerHTML = stom(this.duration); }); }
- The lower control bar is gradually hidden Hiding is not the difficulty , The important thing is to gradually hide , Here we have several solutions :
- Timer
- css3 Animation frames
Here we are 2 To use in combination
First, let's define a set of animations
@keyframes vhide {0% {opacity: 1;}100% {opacity: 0;}}
@-webkit-keyframes vhide {0% {opacity: 1;}100% {opacity: 0;}}
.vhidden {
animation: vhide 3.5s ease-in;
-webkit-animation: vhide 3.5s ease-in;
}
Its role is transparency 3.5 Seconds 1=>0,ease-in Namely From slow to fast Over effect of . Do you understand css Animation can ask Du Niang And then we give the video, when it starts playing events, to Control bar add to vhidden Style class
// Video playback Events
this.video.addEventListener('play',function(){
that.vC.classList.add('vhidden');
})
The test results , Sure enough 3.5s Inside , Control bar Slowly transparent , The problem is 3.5s after , Transparency is back to 1, Here I'll explain , Because the animation frame is rebound by default , We can add a style
.vhidden {
animation: vhide 3.5s ease-in;
-webkit-animation: vhide 3.5s ease-in;
animation-fill-mode:forwards;
-webkit-animation-fill-mode: forwards;
}
CSS3 attribute animation-fill-mode Used to define what an element looks like after the animation .
animation-fill-mode The default value of is none, That is, after the end of the animation, no changes will be made , If you put animation-fill-mode Change to forwards After the animation, the style of the element will become the style specified by the last key frame of the animation .
After adding this pattern , Sure enough 3.5s after , Animation doesn't bounce back anymore , But pay attention here , The control bar is not no longer there, but transparent , If we have a click time to write the control bar , Then click on the control bar , Or trigger events , So , We can also write a paragraph setTimeout Come on , Let the control bar 3.5s Hide behind , You can make your own choice
// Video playback Events
this.video.addEventListener('play',function(){
that.vimg.style.display = 'none';
that.vC.classList.add('vhidden');
that.vCt = setTimeout(function(){
that.vC.style.visibility = 'hidden';
},3400);
})
Why is the animation process 3.5s, However js Yes 3.4s After execution , It's just not written here animation-fill-mode:forwards In the case of insurance
It's playing
Hey , The video can be played ! So now we should think about what we have to do on the air ?
1. The control bar, the progress bar, grows slowly
We need to add a piece to the video timeupdate The event when the audio and video playback position changes
Let's start with the video metadata event , Take down the length of the video
// Get metadata
this.video.addEventListener('loadedmetadata',function(){
that.vDuration = this.duration;
that.vC.querySelector('.duration').innerHTML = stom(that.vDuration);
});
Then calculate the ratio from the video playback progress update event , Set the width of the progress bar
// Events in video playback
this.video.addEventListener('timeupdate', function() {
var currentPos = this.currentTime;// Gets the current playback location
// Update progress bar
var percentage = 100 * currentPos / that.vDuration;
// Set width
that.vC.querySelector('.timeBar').style.width = percentage + '%';
});
We can see that our progress bar is getting bigger and bigger .
2. Current playback time changes
meanwhile , Our current playback time is also displayed in timeupdate Set in the event
// Events in video playback
this.video.addEventListener('timeupdate', function() {
var currentPos = this.currentTime;// Gets the current playback location
// Update progress bar
var percentage = 100 * currentPos / that.vDuration;
that.vC.querySelector('.timeBar').style.width = percentage + '%';
// Update current playback time
that.vC.querySelector('.current').innerHTML = stom(currentPos);
});
Pause or stop it
When we click on the video , If it's a pause , Let's start playing , And trigger the playback event , On the contrary, the video is playing , Click on the video and it will pause , And trigger a pause event .
0. Time frame
La la la , Pause play ,timeupdate Naturally, events don't trigger , The current progress and time will not change .
1. The play button shows
During the pause , Just show the button
// Pause or stop it
this.video.addEventListener('pause',function(){
that.vimg.style.display = 'block';
});
2. The lower control bar shows
The control bar shows , Just get rid of that vhidden Just the style class
// Pause or stop it
this.video.addEventListener('pause',function(){
that.vimg.style.display = 'block';
that.vC.classList.remove('vhidden');
that.vC.style.visibility = 'visible';
});
It seems that there is nothing wrong with this writing , however , If you've written before when you've hidden the control bar setTimeout Words , It's time to get rid of it .
// Pause or stop it
this.video.addEventListener('pause',function(){
that.vimg.style.display = 'block';
that.vC.classList.remove('vhidden');
that.vC.style.visibility = 'visible';
that.vCt && clearTimeout(that.vCt);
});
Fast forward, fast backward
How can a small video player with its mouth in its mouth be less, can it be advanced, retractable and flexible ?
Come on , Let's start with video Add left slide right slide event
// Video gesture right slide event
this.video.addEventListener('swiperight',function(e){
this.currentTime += 5;
});
// Video gesture left slide event
this.video.addEventListener('swipeleft',function(e){
this.currentTime -= 5;
});
Maybe debugging on the computer will change the progress directly 0, At first, I was wondering , It turns out that on the mobile phone webview It seems to be feasible .
About Drag the progress bar to change the video progress I'm not going to write , Because I haven't written yet .
Play full screen
Maybe you will pay more attention to this :
ios End : Remove video label webkit-playsinline Attribute is enough , because ios Yes h5 Of video Tag support is still quite good
// Call native mode Play full screen
pro.nativeMax = function(){
if(!window.plus){
// Not html5+ Environmental Science
return;
}
if($.os.ios){
console.log('ios')
this.video.removeAttribute('webkit-playsinline');
}else if($.os.android){
console.log('android');
var url = this.video.querySelector('source').src;
var Intent = plus.android.importClass("android.content.Intent");
var Uri = plus.android.importClass("android.net.Uri");
var main = plus.android.runtimeMainActivity();
var intent = new Intent(Intent.ACTION_VIEW);
var uri = Uri.parse(url);
intent.setDataAndType(uri, "video/*");
main.startActivity(intent);
}
}
stay initEvent Add click on Full screen event
this.vC.querySelector('.fill').addEventListener('tap',function(){
that.nativeMax();
});
It's a little chicken ribs , You can't have a little generic ?
It's true that I've been thinking about this all night , Decided to bring some more dry goods .
Give me a state first , The default is mini Play
var bvd = function(dom) {
var that = this;
$.ready(function() {
// Get video elements
that.video = document.querySelector(dom || 'video');
// Get video parent element
that.vRoom = that.video.parentNode;
// Element initialization
that.initEm();
// Event initialization
that.initEvent();
// Record information
that.initInfo();
// Current playback mode false by mini Play
that.isMax = false;
})
}
// Record information
pro.initInfo = function() {
var that = this;
// stay onload State, ,offsetHeight To get the correct value
window.onload = function(){
that.miniInfo = {//mini The pattern of state
width: that.video.offsetWidth + 'px',
height: that.video.offsetHeight + 'px',
position: that.vRoom.style.position,
transform: 'translate(0,0) rotate(0deg)'
}
var info = [
document.documentElement.clientWidth || document.body.clientWidth,
document.documentElement.clientHeight || document.body.clientHeigth
],
w = info[0],
h = info[1],
cha = Math.abs(h - w) / 2;
that.maxInfo = {//max The pattern of state
width: h + 'px',
height: w + 'px',
position: 'fixed',
transform: 'translate(-' + cha + 'px,' + cha + 'px) rotate(90deg)'
}
}
}
// Full screen mini Switch between the two modes
pro.switch = function() {
var vR = this.vRoom;
// Get the style information that needs to be transformed
var info = this.isMax ? this.miniInfo : this.maxInfo;
for(var i in info) {
vR.style[i] = info[i];
}
this.isMax = !this.isMax;
}
// Full screen button
this.vC.querySelector('.fill').addEventListener('tap', function() {
//that.nativeMax();
that.switch();
});
Take a look , Take a look at it
It looks like it feels good , utilize css3 The displacement and rotation of , Let the video full screen in front of the screen , But the problem comes with
- Play button as well as Control bar In full screen It seems to be hiding , It's actually video The tag is over the parent element , We adjust accordingly
css
.bad-video {
position: relative;
/*overflow: hidden;*/
background-color: #CCCCCC;
}
js max In the configuration , Set up zIndex value
that.maxInfo = {//max The pattern of state
zIndex:99,
width: h + 'px',
height: w + 'px',
position: 'fixed',
transform: 'translate(-' + cha + 'px,' + cha + 'px) rotate(90deg)'
}
- Horizontal full screen , Left and right slip events do not change with direction
// Video gesture right slide event
this.video.addEventListener('swiperight', function(e) {
console.log('right');
this.currentTime += 5;
});
// Video gesture left slide event
this.video.addEventListener('swipeleft', function(e) {
console.log('left');
this.currentTime -= 5;
});
this TM It's embarrassing , Can't I have a full screen , Mobile phone horizontal , Go up and down, fast forward, fast backward ?
What do you do then , Don't party
Gesture slide Events
Let's give it first video Register an event list
var events = {};
// increase Or delete the event
pro.eve = function(ename, callback, isF) {
if(callback && typeof(callback) == 'function') {
isF && arguments.callee(ename);
events[ename] = callback;
this.video.addEventListener(ename, events[ename]);
console.log(' Add event :' + ename);
return;
}
var fun = events[ename] || function(){};
this.video.removeEventListener(ename, fun);
console.log(' Delete event :' + ename);
return fun;
}
to video Event add a proxy to delete the add event ,isF Whether to delete the same event before adding this event , Because if you use anonymous functions to add events , It can't be deleted , In this way, a proxy can be set up to record dynamically added events in events Inside , Easy to operate
At this time, we add the function of modifying the current playback progress and volume
// Jump to video progress Company second
pro.setCurrentTime = function(t){
this.video.currentTime += t;
}
// Set the volume Company percentage Such as 0.1
pro.setVolume = function(v){
this.video.volume+= v;
}
Then through the agency to video Add events that slide left and right up and down
// Video gesture right slide event
this.eve('swiperight',function(){
that.setCurrentTime(5);
});
// Video gesture left slide event
this.eve('swipeleft', function(e) {
that.setCurrentTime(-5);
});
// Slide events on video gestures
this.eve('swipeup',function(){
that.setVolume(0.2);
});
// Video gesture slide event
this.eve('swipedown', function(e) {
that.setCurrentTime(-0.2);
});
ok, Sliding events in four directions have been added , But this is mini Mode playback Events , In full screen , Events in four directions did not follow video The direction of the elements changes , This requires the most stupid way to determine whether the full screen triggers the event
// Video gesture right slide event
this.eve('swiperight',function(){
if(that.isMax){
return that.setVolume(0.2);
}
that.setCurrentTime(5);
});
// Video gesture left slide event
this.eve('swipeleft', function() {
if(that.isMax){
return that.setVolume(-0.2);
}
that.setCurrentTime(-5);
});
// Slide events on video gestures
this.eve('swipeup',function(){
if(that.isMax){
return that.setCurrentTime(-5);
}
that.setVolume(0.2);
});
// Video gesture slide event
this.eve('swipedown', function() {
if(that.isMax){
return that.setCurrentTime(5);
}
that.setVolume(-0.2);
});
What about? , Although it looks a little bit stupid, But it's very practical
5+ Client full screen solution
Although in 5+ client ,android You can call the native way to play , But it's not good enough , We can look at another set of solutions
On initialization , Record mini Style of time , In full screen , By modifying the video width to the screen height , Change video height to video width , recycling 5+ The screen rotates , Set full screen , hide the status bar
0) Remove gesture event judgment
Because it's time to change the direction of mobile devices , therefore , The direction of the gesture changes with the direction of the device
1) Remove css3 Rotation and displacement
// Record information
pro.initInfo = function() {
var that = this;
// stay onload State, ,offsetHeight To get the correct value
window.onload = function() {
that.miniInfo = { //mini The pattern of state
zIndex: 1,
width: that.video.offsetWidth + 'px',
height: that.video.offsetHeight + 'px',
position: that.vRoom.style.position
}
that.maxInfo = { //max The pattern of state
zIndex: 99,
width: '100%',
height: that.sw + 'px',
position: 'fixed'
}
}
}
2) This use 5+ Set full screen and hide status bar
// Full screen mini Switch between the two modes
pro.switch = function() {
var vR = this.vRoom;
// Get the style information that needs to be transformed
var info = this.isMax ? this.miniInfo : this.maxInfo;
for(var i in info) {
vR.style[i] = info[i];
}
this.isMax = !this.isMax;
plus.navigator.setFullscreen(this.isMax);
if(this.isMax) {
// Horizontal screen
plus.screen.lockOrientation("landscape-primary");
} else {
// Vertical screen
plus.screen.lockOrientation("portrait-primary");
}
}
3) In full screen mode ,android End return key , Trigger to exit full screen
pro.initEvent = function() {
//....... Omit other code
this.oback = $.back;
// Listen to Android return key
$.back = function() {
if(that.isMax) {
that.switch();
return;
}
that.oback();
}
}
design sketch
5+ Gravity switch full screen
Hey , How can a player be less mobile Automatic switch Horizontal and vertical screens ? How to manually switch full screen , Next, gravity sensor switches the horizontal screen , Need to use 5+ Of API Accelerometer Acceleration sensing
In short : Gravitational acceleration can be thought of as a ball in a coordinate system Acceleration in three directions . Always follow the screen of your mobile phone
What is acceleration ? forehead , It's from the physics book
The mobile phone is placed horizontally upward y Positive axis To the right is x Positive axis , Outward is z Positive axis
What is xyz Axis ? forehead , It's from high mathematics books
Oh dear , You put your mobile phone upright on the ground , You just walk up there , Now you're standing on the screen of your phone , And then your right hand opens and straightens , This is it. x Axis , You're looking ahead , This is it. y Axis , It's on top of your head z Axis . That's clear. No , But it's not really about stepping on your cell phone ,23333
You can also choose to view other explanations :Android- Sensor development - Direction judgment
- x,y Axis change : When the mobile phone screen is placed horizontally upward : (x,y,z) = (0, 0, -9.81) When the top of the phone is raised : y Reduce , And it's negative When the bottom of the phone is raised : y increase , And it's positive When the right side of the phone is raised : x Reduce , And it's negative When the left side of the phone is raised : x increase , And it's positive
- z Change of axis : When the mobile phone screen is placed horizontally upward ,z= -9.81 When the phone screen is placed vertically , z= 0 When the mobile phone screen is placed horizontally down ,z= 9.81
- Screen vertical and horizontal switching conditions y<=-5 when , Switch to vertical x<=-5 when , Change to horizontal
ok, We added 2 A way , Used to turn on and off device monitoring
// Turn on direction sensing
pro.startWatchAcc = function(){
var that = this;
this.watchAccFun = plus.accelerometer.watchAcceleration(function(a) {
if(that.getIsMax()){
// The current state is full screen
// Determine whether the vertical screen is satisfied Mini state
a.yAxis>=5 && that.setIsMax(false);
}else{
// At present, it is Mini state
// Judge whether it satisfies the full screen Max state
Math.abs(a.xAxis) >=5 && that.setIsMax(true);
}
}, function(e) {
// It's a big deal to make a mistake It doesn't rotate automatically Let it be manual Switch
console.log("Acceleration error: " + e.message);
that.clearWatchAcc();
},{
frequency:1200
});
}
// Turn off directional sensing
pro.clearWatchAcc = function(){
this.watchAccFun && plus.accelerometer.clearWatch(this.watchAccFun);
}
Then, the direction monitoring is turned on by default during initialization
var bvd = function(dom) {
var that = this;
$.ready(function() {
//...
})
$.plusReady(function() {
that.startWatchAcc();
})
}
Then change the horizontal full screen to , Can be two-way horizontal screen
Real machine debugging to see
Hey , Let's add a lock button for full screen playback , Let the device not monitor Gravity induction , Also does not respond to the video click play pause event
Make a lock button first
Of course , Lock picture , The address was changed to use base64, It's better to use js Dynamically generate tags
Set its basic style , Keep right , Vertical center up and down , Hide by default
.lock {
padding: .3rem;
width: 3rem;
height: 3rem;
position: absolute;
right: .5rem;
top: 50%;
transform: translateY(-50%);
-webkit-transform: translateY(-50%);
visibility: hidden;
}
good , Let's sort out the logic ,
1) Default in mini When the play ,lock hide 2) When playing full screen ,lock Show , But it also follows the control bar stay 4s Hide inside right 3) When full screen pauses ,lock With the control bar Always show 4) Click on lock When locked , The prompt is locked , The control bar is hidden immediately ,lock4s Hide inside right , Video click events are replaced by display lock Icon ,android The return key event is changed to do nothing , Turn off gravity monitoring 5) Click on lock When the unlock , The prompt is unlocked ,android The return key is changed to Switch to a mini state , Turn on gravity monitoring
I wipe , In fact, it's quite depressing to do it , The main reason is that logic processing is painful
0) Add an animation that moves right ,3s After the delay 1s Inside After executing the animation
@keyframes lockhide {0% {transform: translate(0%,-50%);}100% {transform: translate(120%,-50%);}}
webkit-keyframes lockhide {0% {transform: translate(0%,-50%);}100% {transform: translate(120%,-50%);}}
.lockhidden {
animation: lockhide 1s 3s linear;
-webkit-animation: lockhide 1s 3s linear;
animation-fill-mode:forwards;
-webkit-animation-fill-mode: forwards;
}
1) Show... In full screen lock
pro.switch = function() {
//...
// In full screen According to lock Icon
this.vlock.style.visibility = this.isMax ? 'visible' : 'hidden';
}
2) When playing full screen ,lock Show , But it also follows the control bar stay 4s Hide inside right We add lock The hidden animation of ,
3) When full screen pauses ,lock With the control bar Always show
4) Click on lock When locked , The prompt is locked , The control bar is hidden immediately ,lock4s Hide inside right , Video click events are replaced by display lock Icon ,android The return key event is changed to do nothing , Turn off gravity monitoring 5) Click on lock When the unlock , The prompt is unlocked ,android The return key is changed to Switch to a mini state , Turn on gravity monitoring
// Lock screen
pro.lockScreen = function() {
$.toast(' Lock screen ');
var that = this;
// Replace video Click the event as Show lock Icon , And save video Previous events
this.videoTapFn = this.eve('tap', function() {
that.lockT = setTimeout(function(){
that.vlock.classList.add('lockhidden');
},500);
// Restart playing styles
that.vlock.classList.remove('lockhidden');
that.vlock.style.visibility = 'visible';
}, true);
// Hide the control bar
this.vC.style.visibility = 'hidden';
// to Lock Icon added Hidden style class
this.vlock.classList.add('lockhidden');
// When you lock the screen , Don't monitor gravity sensing
this.clearWatchAcc();
// Identifies the currently changed Lock state
this.isLock = true;
}
// Unlock screen
pro.unlockScreen = function() {
$.toast(' Unlock screen ');
// Replace with video Previous click events
this.eve('tap', this.videoTapFn, true);
// to Lock The icon is clear Hidden style class
this.vlock.classList.remove('lockhidden');
// When you don't lock the screen , Monitoring gravity sensing
this.startWatchAcc();
// Identifies the currently changed Lock state
this.isLock = false;
}
666) Finally, to our dear lock Add a touch event to the icon , as well as android Return key event change
// Full screen when Lock click events
this.vlock.addEventListener('tap', function() {
if(that.isLock) {
that.unlockScreen();
return;
}
that.lockScreen();
});
this.oback = $.back;
// Listen to Android return key
$.back = function(){
if(that.isMax){
if(!that.isLock){
// In full screen mode Press the back key when ,1s It doesn't monitor gravity , Prevent return Mini State time and gravimetry are concurrent events
setTimeout(function(){
that.startWatchAcc();
},1000);
that.clearWatchAcc();
that.switch();
}
return;
}
that.oback();
}
}
Okay ! this paper 5+ Full screen demo Source code address
It's not easy to blog , But that kind of sharing mood is very good , It's another kind of review and progress ?
Thank you .
This article related article :H5 Build your own video player special column
Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .
版权声明
本文为[:::::::]所创,转载请带上原文链接,感谢
边栏推荐
- xmppmini 專案詳解:一步一步從原理跟我學實用 xmpp 技術開發 4.字串解碼祕笈與訊息包
- 大数据应用的重要性体现在方方面面
- (2)ASP.NET Core3.1 Ocelot路由
- 01 . Go语言的SSH远程终端及WebSocket
- 2018中国云厂商TOP5:阿里云、腾讯云、AWS、电信、联通 ...
- ipfs正舵者Filecoin落地正当时 FIL币价格破千来了
- “颜值经济”的野望:华熙生物净利率六连降,收购案遭上交所问询
- The difference between Es5 class and ES6 class
- 技術總監,送給剛畢業的程式設計師們一句話——做好小事,才能成就大事
- hadoop 命令总结
猜你喜欢

Network security engineer Demo: the original * * is to get your computer administrator rights! 【***】

Basic principle and application of iptables

Working principle of gradient descent algorithm in machine learning

Existence judgment in structured data

Tool class under JUC package, its name is locksupport! Did you make it?

TRON智能钱包PHP开发包【零TRX归集】

Character string and memory operation function in C language

DevOps是什么

从海外进军中国,Rancher要执容器云市场牛耳 | 爱分析调研

使用NLP和ML来提取和构造Web数据
随机推荐
微服務 - 如何解決鏈路追蹤問題
Details of dapr implementing distributed stateful service
In depth understanding of the construction of Intelligent Recommendation System
速看!互联网、电商离线大数据分析最佳实践!(附网盘链接)
Didi elasticsearch cluster cross version upgrade and platform reconfiguration
The practice of the architecture of Internet public opinion system
EOS创始人BM: UE,UBI,URI有什么区别?
Keyboard entry lottery random draw
This article will introduce you to jest unit test
全球疫情加速互联网企业转型,区块链会是解药吗?
Analysis of ThreadLocal principle
Real time data synchronization scheme based on Flink SQL CDC
制造和新的自动化技术是什么?
有关PDF417条码码制的结构介绍
Pycharm快捷键 自定义功能形式
数字城市响应相关国家政策大力发展数字孪生平台的建设
03_ Detailed explanation and test of installation and configuration of Ubuntu Samba
High availability cluster deployment of jumpserver: (6) deployment of SSH agent module Koko and implementation of system service management
DevOps是什么
如何将数据变成资产?吸引数据科学家