当前位置:网站首页>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 .
版权声明
本文为[:::::::]所创,转载请带上原文链接,感谢
边栏推荐
- Want to do read-write separation, give you some small experience
- 直播预告 | 微服务架构学习系列直播第三期
- Vue 3 responsive Foundation
- 恕我直言,我也是才知道ElasticSearch条件更新是这么玩的
- 使用NLP和ML来提取和构造Web数据
- 网络安全工程师演示:原来***是这样获取你的计算机管理员权限的!【维持】
- 幽默:黑客式编程其实类似机器学习!
- Elasticsearch database | elasticsearch-7.5.0 application construction
- Asp.Net Core learning notes: Introduction
- Filecoin最新动态 完成重大升级 已实现四大项目进展!
猜你喜欢

Pycharm快捷键 自定义功能形式

做外包真的很难,身为外包的我也无奈叹息。

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

DRF JWT authentication module and self customization

你的财务报告该换个高级的套路了——财务分析驾驶舱

Character string and memory operation function in C language

Grouping operation aligned with specified datum

简直骚操作,ThreadLocal还能当缓存用

Swagger 3.0 天天刷屏,真的香嗎?

hadoop 命令总结
随机推荐
Swagger 3.0 天天刷屏,真的香嗎?
条码生成软件如何隐藏部分条码文字
Real time data synchronization scheme based on Flink SQL CDC
采购供应商系统是什么?采购供应商管理平台解决方案
PHP应用对接Justswap专用开发包【JustSwap.PHP】
Top 10 best big data analysis tools in 2020
连肝三个通宵,JVM77道高频面试题详细分析,就这?
前端模組化簡單總結
GUI 引擎评价指标
PN8162 20W PD快充芯片,PD快充充电器方案
Leetcode's ransom letter
大数据应用的重要性体现在方方面面
【新閣教育】窮學上位機系列——搭建STEP7模擬環境
使用 Iceberg on Kubernetes 打造新一代云原生数据湖
Network programming NiO: Bio and NiO
EOS创始人BM: UE,UBI,URI有什么区别?
Flink on paasta: yelp's new stream processing platform running on kubernetes
Sort the array in ascending order according to the frequency
[C#] (原創)一步一步教你自定義控制元件——04,ProgressBar(進度條)
Tool class under JUC package, its name is locksupport! Did you make it?