1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > angular开发中自定义HTML5的video控制面板实现刷新 播放 进度条控制 倍数 声音 全屏等功能

angular开发中自定义HTML5的video控制面板实现刷新 播放 进度条控制 倍数 声音 全屏等功能

时间:2022-08-29 04:38:54

相关推荐

angular开发中自定义HTML5的video控制面板实现刷新 播放 进度条控制 倍数 声音 全屏等功能

开发中遇到需要自定义HTML5的video控制面板功能,结合网上资料进行了优化和实现,还可以自定义其它功能,备份下来:

1.实现效果图:

2.html代码片段:

<div class="video-box"><!--video 盒子--><div class="video-box-body"><video class="video-body" [src]="playPath">您的浏览器不支持 video 标签。</video><!--控制条盒子--><div class="video-control"><div class="video-control-left"><!--刷新键--><div class="control-btn pull-left" (click)="loadHandle()" title="刷新"><i class="fa fa-refresh"></i></div><!--暂停/播放键--><div class="control-btn pull-left" [hidden]="errorFlag" (click)="playPauseHandle()" [title]="playPauseTitle"><i id="playPauseFa" class="fa fa-play"></i></div><div class="control-btn pull-left errorColor" [hidden]="!errorFlag" [title]="playPauseTitle"><i class="fa fa-play"></i></div></div><div class="progress-box"><div class="progress-box-body"><!--播放时长--><div class="current-time pull-left" id="currentTime">00:00</div><div class="durationbar-box pull-left"><!--总视频长度进度条--><div class="durationbar" id="durationBar"><!--缓冲进度条--><div class="bufferbar" id="bufferBar"></div><!--正在播放进度条--><div class="currentbar" id="currentBar"></div><div class="drawbar" id="drawBar"></div></div></div><!--总时长--><div class="duration-time pull-left" id="durationTime">00:00</div></div></div><div class="video-control-right"><!--倍数键--><div class="control-multiple pull-left" title="倍数"><p-dropdown id="multipleId" [options]="multiples" [(ngModel)]="multiple" (onChange)="multipleHandle()"[disabled]="errorFlag" [style]="{'min-width':'20px', 'width': '100%'}"></p-dropdown></div><!--音量键--><div class="control-btn pull-left" [hidden]="errorFlag" (click)="mutedHandle()" [title]="mutedTitle"><i id="mutedFa" class="fa fa-volume-up"></i></div><div class="control-btn pull-left errorColor" [hidden]="!errorFlag" [title]="mutedTitle"><i class="fa fa-volume-up"></i></div><!--全屏键--><div class="control-btn pull-left" *ngIf="!isFullScreen" (click)="fullScreenHandle()" title="全屏"><i class="fa fa-expand"></i></div><div class="control-btn pull-left" *ngIf="isFullScreen" (click)="exitFullScreenHandle()" title="还原"><i class="fa fa-compress"></i></div></div></div></div></div>

3.scss样式代码:

/*video样式*/.video-box {overflow: hidden;background: #000;width: 100%;height: calc(100% - 10px);display: block;margin: 0 auto;-webkit-transition-duration: 300ms;-moz-transition-duration: 300ms;-ms-transition-duration: 300ms;-o-transition-duration: 300ms;transition-duration: 300ms;z-index: 10;}/*video body样式*/.video-box-body {position: relative;width: 100%;height: 100%;margin: 0 auto;overflow: hidden;.video-body {display: block;width: 100%;height: 100%;position: absolute;left: 0;top: 0;z-index: 15;object-fit: fill;}}/*控制条样式*/.video-control {position: absolute;width: 100%;height: 50px;padding: 10px;line-height: 30px;background: rgba(0, 0, 0, .5);z-index: 99999999999;left: 0;right: 0;bottom: 0;div {display: inline-block;}.control-btn {display: inline-block;width: 30px;height: 30px;background: transparent;cursor: pointer;font-size: 20px;color: white;border-radius: 100%;text-align: center;&:hover {background-color: rgba(0, 0, 0, 0.5);border-color: rgba(0, 0, 0, 0.5);}}// 左.video-control-left {position: absolute;height: 30px;z-index: 5;.control-btn {margin-right: 10px;&:last-child {margin: 0;}}}// 中.progress-box {width: 100%;height: 30px;padding: 0 130px 0 70px;.progress-box-body {width: 100%;height: 100%;.current-time, .duration-time {width: 60px;text-align: center;color: #fff;}.current-time {margin-right: -60px;position: relative;z-index: 5;}.duration-time {margin-left: -60px;position: relative;z-index: 5;}.durationbar-box {width: 100%;padding: 0 70px;}.durationbar {width: 100%;height: 10px;margin-top: 10px;background: rgba(65, 62, 62, 1);-webkit-border-radius: 50px;-moz-border-radius: 50px;-ms-border-radius: 50px;-o-border-radius: 50px;border-radius: 50px;position: relative;}.bufferbar, .currentbar {position: absolute;left: 0;top: 0;height: 100%;width: 0;background: rgba(117, 114, 114, 1);-webkit-border-radius: 50px;-moz-border-radius: 50px;-ms-border-radius: 50px;-o-border-radius: 50px;border-radius: 50px;z-index: 5;cursor: pointer;}.currentbar {background: #fff;z-index: 10;}.drawbar {position: absolute;background: #fff;width: 20px;height: 20px;left: 0;top: -5px;z-index: 10;-webkit-border-radius: 50px;-moz-border-radius: 50px;-ms-border-radius: 50px;-o-border-radius: 50px;border-radius: 50px;cursor: pointer;}}}// 右.video-control-right {position: absolute;height: 30px;margin-left: -130px;z-index: 5;.control-btn {margin-left: 10px;&:first-child {margin: 0;}}}}// 倍数:host ::ng-deep .control-multiple {width: 50px;height: 30px;border-radius: 5px;.ui-dropdown {border: none;&:not(.ui-state-disabled):hover {background-color: rgba(0, 0, 0, 0.5);border-color: rgba(0, 0, 0, 0.5);.ui-dropdown-label {background: transparent;}}.ui-inputtext {color: white;}.ui-dropdown-label {background: transparent;}}}video:-webkit-full-screen {z-index: 9 !important;width: 100% !important;height: 100% !important;}video::-webkit-media-controls {display: none !important;}.errorColor {color: #838383 !important;}

4.ts代码处理:

public playPath: any; // 播放路径public videoDom: any; // 播放器对象public playPauseDom: any; // 播放/暂停图标对象public playPauseTitle: string = "播放"; // 播放/暂停提示public mutedDom: any; // 音量图标对象public mutedTitle: string = "关闭"; // 开启/关闭提示public isFullScreen: boolean = false; // 是否全屏public multiples: any = []; // 播放的倍数public multiple: number = 1; // 选择的倍数public errorFlag: boolean = true; // 加载错误constructor(public viewVideoService:ViewVideoService,private renderer: Renderer2,private el: ElementRef) {this.multiples = [{label: '5.0X',value: 5},{label: '2.0X',value: 2},{label: '1.5X',value: 1.5},{label: '1.0X',value: 1},{label: '0.5X',value: 0.5}];}ngOnInit() {// 路径源this.playPath=this.viewVideoService.getPath();}ngAfterViewInit() {// video等元素this.videoDom = this.el.nativeElement.querySelector("video");this.playPauseDom = this.el.nativeElement.querySelector("#playPauseFa");this.mutedDom = this.el.nativeElement.querySelector("#mutedFa");// 去除倍数播放下拉框多余元素let multipleElement = this.el.nativeElement.querySelector("#multipleId");let dropdownElement = multipleElement ? multipleElement.querySelector(".ui-dropdown-trigger"):null;if (dropdownElement) dropdownElement.remove();// 事件this.eventHandle();}/*** 结束或暂停播放状态图标切换**/private pauseHandle() { // 结束或暂停// 刷新后已经暂停this.playPauseTitle = '播放';if (this.playPauseDom) {//通过操作不同的class,来切换键的形态this.renderer.removeClass(this.playPauseDom, 'fa-pause');this.renderer.addClass(this.playPauseDom, 'fa-play');}}/*** 刷新视频,直接调用load()方法就行**/public loadHandle() { // 刷新this.videoDom.load();this.multipleHandle();// 刷新后已经暂停this.pauseHandle();}/*** 播放/暂停功能**/public playPauseHandle() { // 播放暂停//paused 返回的是视频是否是暂停状态,返回的是一个布尔值if(this.videoDom.paused){this.videoDom.play();this.playPauseTitle = '暂停';if (this.playPauseDom) {//通过操作不同的class,来切换键的形态this.renderer.removeClass(this.playPauseDom, 'fa-play');this.renderer.addClass(this.playPauseDom, 'fa-pause');}}else{this.videoDom.pause();this.pauseHandle();}}/*** 播放倍数调节**/public multipleHandle() {this.videoDom.playbackRate = this.multiple;}/*** 音量键的开启和关闭**/public mutedHandle() {//如果为静音则开启,如果为开启状态则关闭this.videoDom.muted=!this.videoDom.muted;if (this.videoDom.muted) { // 禁音状态this.mutedTitle = '开启';if (this.mutedDom) {//通过操作不同的class,来切换键的形态this.renderer.removeClass(this.mutedDom, 'fa-volume-up');this.renderer.addClass(this.mutedDom, 'fa-volume-off');}} else { // 开启状态this.mutedTitle = '关闭';if (this.mutedDom) {//通过操作不同的class,来切换键的形态this.renderer.removeClass(this.mutedDom, 'fa-volume-off');this.renderer.addClass(this.mutedDom, 'fa-volume-up');}}}/*** 全屏调节**/public fullScreenHandle() {const videoBox = this.el.nativeElement.querySelector(".video-box");if(videoBox.webkitRequestFullScreen){videoBox.webkitRequestFullScreen();} else if (videoBox.mozRequestFullScreen){videoBox.mozRequestFullScreen();} else {videoBox.requestFullScreen();}this.isFullScreen = true;}/*** 退出全屏**/public exitFullScreenHandle() {const videoBox = this.el.nativeElement.querySelector(".video-box");if(videoBox.ownerDocument.webkitCancelFullScreen){videoBox.ownerDocument.webkitCancelFullScreen();} else if (videoBox.ownerDocument.mozCancelFullScreen){videoBox.ownerDocument.mozCancelFullScreen();} else {videoBox.ownerDocument.exitFullscreen();}this.isFullScreen = false;}/*** 事件监听定义**/public eventHandle() {// 键盘事件监听this.keyEvent();// 退出全屏监听this.escExitFullScreen();// 播放时间监听this.playTimeHanle();// video控制面板显示/隐藏处理this.showHideControlsHandle();}/*** 键盘事件处理**/private keyEvent() {let that = this;let vol = 0.1; //1代表100%音量,每次增减0.1let time = 5; //单位秒,每次增减5秒//键盘事件document.onkeyup = function (event) {let e = event || window.event || arguments.callee.caller.arguments[0];//鼠标上下键控制视频音量if (e && e.keyCode === 38) {// 按 向上键that.videoDom.volume !== 1 ? that.videoDom.volume += vol : 1;return false;} else if (e && e.keyCode === 40) {// 按 向下键that.videoDom.volume !== 0 ? that.videoDom.volume -= vol : 1;return false;} else if (e && e.keyCode === 37) {// 按 向左键that.videoDom.currentTime !== 0 ? that.videoDom.currentTime -= time : 1;return false;} else if (e && e.keyCode === 39) {// 按 向右键that.videoDom.currentTime !== that.videoDom.duration ? that.videoDom.currentTime += time : 1;return false;} else if (e && e.keyCode === 32) {// 按空格键 判断当前是否暂停that.playPauseHandle();return false;}};}/*** 验证是否全屏ESC退出处理**/private escExitFullScreen(){const videoBox = this.el.nativeElement.querySelector(".video-box");let videoDoc = videoBox.ownerDocument;let that = this;let exitHandler = function() {let isFull = videoDoc.webkitIsFullScreen;if(isFull === undefined) isFull = false;if (!isFull) that.isFullScreen = false;};videoBox.addEventListener('fullscreenchange', exitHandler);videoBox.addEventListener('webkitfullscreenchange', exitHandler);videoBox.addEventListener('mozfullscreenchange', exitHandler);}/*** 因为我们获取的视频时长是秒数,所以我们需要将秒数转化为我们常见的时间格式**/private initTimeLength(timeLength) { // 根据秒数格式化时间timeLength = parseInt(timeLength);let second = timeLength % 60;let minute = (timeLength - second) / 60;return (minute<10?"0"+minute:minute)+":"+(second<10?"0"+second:second);};/*** 视频时间等效果处理**/private playTimeHanle() {this.videoDom.addEventListener('loadeddata', () => {const durationTime = this.el.nativeElement.querySelector("#durationTime");durationTime.innerHTML = this.initTimeLength(this.videoDom.duration);// 缓冲进度const bufferBar = this.el.nativeElement.querySelector("#bufferBar");bufferBar.style.width = '0px';this.bufferHandle(); // 缓冲进度条处理this.videoSeekHandle(); // 点击进度条播放处理this.errorFlag = false;});// ontimeupdate 当前视频播放位置反生改变触发的事件;this.videoDom.addEventListener('timeupdate', () => {// 视频时长let durationProgress=this.videoDom.duration;// currentTime 当前播放时长let currentTimeProgress=this.videoDom.currentTime;// 将当前播放时长填入左边时长元素中const currentTime = this.el.nativeElement.querySelector("#currentTime");currentTime.innerHTML = this.initTimeLength(this.videoDom.currentTime);// 求当前播放时长的进度,从而显示出来进度条let currentWidth=100*(currentTimeProgress/durationProgress);const drawBar = this.el.nativeElement.querySelector("#drawBar");const durationBar = this.el.nativeElement.querySelector("#durationBar");const currentBar = this.el.nativeElement.querySelector("#currentBar");let currentLeft=currentWidth-((drawBar.offsetWidth/2)/durationBar.offsetWidth*100);currentBar.style.width = currentWidth > 0 ? currentWidth.toFixed(1)+'%' : '0px';drawBar.style.left = currentLeft > 0 ? currentLeft.toFixed(1)+'%': '0px';});// 播放结束状态this.videoDom.addEventListener('ended', () => {// 播放结束后已经暂停this.pauseHandle();// 是否需要展示隐藏控制面板this.hideControls();});// 播放错误this.videoDom.addEventListener('error', () => {this.errorFlag = true;});}/*** 缓冲进度条处理**/private bufferHandle() {//视频时长var maxduration = this.videoDom.duration;//当前缓冲进度时长结束位置var currentBuffer = this.videoDom.buffered.end(0);// 求取百分比var percentage = 100 * currentBuffer / maxduration;const bufferBar = this.el.nativeElement.querySelector("#bufferBar");bufferBar.style.width = percentage.toFixed(1)+'%';// 在范围内每500毫秒进行一次递归,也就是调用一下自己;if(currentBuffer<maxduration){setTimeout( () => {this.bufferHandle();},500);}}/*** video控制面板显示/隐藏处理**/private showHideControlsHandle() {this.videoDom.addEventListener('mouseover', () => { this.showControls(); });this.videoDom.addEventListener('mouseout', () => { this.hideControls(); });const videoControls = this.el.nativeElement.querySelector(".video-control");videoControls.addEventListener('mouseover', () => { this.showControls(); });videoControls.addEventListener('mouseout', () => { this.hideControls(); });}// 显示video的控制面板private showControls(){const videoControls = this.el.nativeElement.querySelector(".video-control");videoControls.style.opacity = 1;}// 隐藏video的控制面板private hideControls(){const videoControls = this.el.nativeElement.querySelector(".video-control");if(this.videoDom.paused){ // 暂停videoControls.style.opacity = 1;} else {videoControls.style.opacity = 0;}}/*** 点击进度条播放处理**/private videoSeekHandle() {const currentBar = this.el.nativeElement.querySelector("#currentBar");const bufferBar = this.el.nativeElement.querySelector("#bufferBar");currentBar.addEventListener('mousedown', (e) => { this.videoSeekChange(e); });bufferBar.addEventListener('mousedown', (e) => { this.videoSeekChange(e); });}// 点击进度条的处理方法private videoSeekChange(e) {const durationBar = this.el.nativeElement.querySelector("#durationBar");let length = e.offsetX;let percent = length / durationBar.offsetWidth;this.videoDom.currentTime = percent * this.videoDom.duration; // 更改currentTime后会触发timeupdate事件}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。