高防服务器

Angular中如何自定义视频播放器


Angular中如何自定义视频播放器

发布时间:2022-05-04 19:04:12 来源:高防服务器网 阅读:96 作者:iii 栏目:web开发

本篇内容主要讲解“Angular中如何自定义视频播放器”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Angular中如何自定义视频播放器”吧!

实现的功能如下:

  • 播放 / 停止

  • 快退 / 快进 / 倍速

  • 声音开 / 声音关

  • 进入全屏 / 退出全屏

  • 进入画中画 / 退出画中画 【安卓平板不支持,不建议使用】

  • 经过时长 / 总时长

  • 播放进度条功能:支持点击,拖拽进度

  • 声音进度条功能:支持点击,拖拽进度

如图:

下面我们来一一实现:

这里的重点不在布局,我们简单来定义一下:

<!-- app.component.html -->    <div class="video-page">    <div class="video-tools">      <button nz-button nzType="primary" (click)="play('btn')" style="margin-right: 12px;">播放 ✅</button>      <button nz-button nzType="primary" (click)="pause('btn')">暂停 ✅</button>      <ng-container>        <button nz-button nz-dropdown [nzDropdownMenu]="menuForward" nzPlacement="bottomCenter" style="margin: 0 12px;">快进 ✅</button>          <nz-dropdown-menu #menuForward="nzDropdownMenu">            <ul nz-menu>              <li nz-menu-item (click)="forwardSecond(10)">快进 10 s</li>              <li nz-menu-item (click)="forwardSecond(20)">快进 20 s</li>            </ul>          </nz-dropdown-menu>      </ng-container>      <ng-container>        <button nz-button nz-dropdown [nzDropdownMenu]="menuBack" nzPlacement="bottomCenter">快退 ✅</button>          <nz-dropdown-menu #menuBack="nzDropdownMenu">            <ul nz-menu>              <li nz-menu-item (click)="retreatSecond(10)">快退 10 s</li>              <li nz-menu-item (click)="retreatSecond(20)">快退 20 s</li>            </ul>          </nz-dropdown-menu>      </ng-container>      <ng-container>        <button nz-button nz-dropdown [nzDropdownMenu]="speedUp" nzPlacement="bottomCenter" style="margin: 0 12px;">倍速 ✅</button>          <nz-dropdown-menu #speedUp="nzDropdownMenu">            <ul nz-menu>              <li nz-menu-item (click)="speedUpVideo(1)">正常</li>              <li nz-menu-item (click)="speedUpVideo(2)">2 倍</li>              <li nz-menu-item (click)="speedUpVideo(4)">4 倍</li>            </ul>          </nz-dropdown-menu>      </ng-container>      <button nz-button nzType="primary" (click)="openOrCloseVoice()">声音开 / 声音关 ✅</button>      <button nz-button nzType="primary" style="margin: 0 12px;" (click)="toFullScreen()">全屏 ✅</button>      <br />      <button nz-button nzType="primary" style="margin-top: 12px;" (click)="entryInPicture()">进入画中画 ⚠️ 安卓平板不支持</button>      <button nz-button nzType="primary" style="margin: 12px 12px 0 12px;" (click)="exitInPicture()">退出画中画 ⚠️ 安卓平板不支持</button>      <br />      <div style="display: flex; justify-content: flex-start; align-items: center; margin: 12px 0;">        经过时长 / 总时长 : ✅ {{ currentTime }}  / {{ totalTime }}      </div>      <!-- 进度条 -->      <div style="display: flex; justify-content: flex-start; align-items: center; margin: 12px 0;">        进度条:✅        <div          class="custom-video_control-bg"          (mousedown)="handleProgressDown($event)"          (mousemove)="handleProgressMove($event)"          (mouseup)="handleProgressUp($event)"        >          <div            class="custom-video_control-bg-outside"            id="custom-video_control-bg-outside"          >            <span              class="custom-video_control-bg-inside"              id="custom-video_control-bg-inside"            ></span>            <span              class="custom-video_control-bg-inside-point"              id="custom-video_control-bg-inside-point"            ></span>          </div>        </div>      </div>      <div style="display: flex; justify-content: flex-start; align-items: center; margin: 12px 0;">        声音条:✅        <div class="custom-video_control-voice">          <span class="custom-video_control-voice-play">            <i nz-icon nzType="sound" nzTheme="outline"></i>          </span>          <div            class="custom-video_control-voice-bg"            id="custom-video_control-voice-bg"            (mousedown)="handleVolProgressDown($event)"            (mousemove)="handleVolProgressMove($event)"            (mouseup)="handleVolProgressUp($event)"          >            <div               class="custom-video_control-voice-bg-outside"              id="custom-video_control-voice-bg-outside"            >              <span                 class="custom-video_control-voice-bg-inside"                id="custom-video_control-voice-bg-inside"              ></span>              <span                 class="custom-video_control-voice-bg-point"                id="custom-video_control-voice-bg-point"              ></span>            </div>          </div>        </div>      </div>    </div>    <div class="video-content">      <video id="video" class="video" style="width: 100%" poster="assets/poster.png">        <source type="video/mp4" src="assets/demo.mp4">        Sorry, your browser doesn't support.      </video>    </div>  </div>

这里使用了 angular ant design,之前写了一篇相关文章,还不熟悉的读者可前往 Angular 结合 NG-ZORRO 快速开发

播放 / 停止

这里直接调用 video 对象的方法 play()pause():

// app.component.ts    // 播放按钮事件  play(flag: string | undefined) {    if(flag) this.videoState.playState = true    this.videoState.play = true    this.video.play()  }  // 暂停按钮事件  pause(flag: string | undefined): void {    if(flag) this.videoState.playState = false    this.video.pause()    this.videoState.play = false  }

这里自定义的 playpause 方法加上了一个标志,对下下面要讲的进度条的控制有帮助,上面的代码可以更加简洁,读者可以简写下。

快退 / 快进 / 倍速

这里的快退,快进和倍速设置了不同的选项,通过参数进行传递:

// app.component.ts    // 快进指定的时间  forwardSecond(second: number): void {    this.video.currentTime += second; // 定位到当前的播放时间 currentTime  }    // 后退指定的时间  retreatSecond(second: number): void {    this.video.currentTime -= second  }    // 倍速  speedUpVideo(multiple: number): void {    this.video.playbackRate = multiple; // 设定当前的倍速 playbackRate  }

声音开 / 声音关

声音的开关使用 videomuted 属性即可:

// app.component.ts    // 开或关声音  openOrCloseVoice(): void {    this.video.muted = !this.video.muted;  }

进入全屏 / 退出全屏

全屏的操作也是很简单,使用 webkitRequestFullScreen

// app.component.ts    // 全屏操作  toFullScreen(): void {    this.video.webkitRequestFullScreen()  }

全屏后,按 esc 可退出全屏

进入画中画 / 退出画中画

画中画相当于弹窗缩小视频~

// app.component.ts    // 进入画中画  entryInPicture(): void {    this.video.requestPictureInPicture()    this.video.style.display = "none"  }    // 退出画中画  exitInPicture(): void {    if(this.document.pictureInPictureElement) {      this.document.exitPictureInPicture()      this.video.style.display = "block"    }  }

设置 video 的样式,是为了看起来不突兀…

经过时长 / 总时长

记录视频的总时长和视频当前的播放时长。我们已经来组件的时候就获取视频的元信息,得到总时长;在视频播放的过程中,更新当前时长。

// app.component.ts    // 初始化 video 的相关的事件  initVideoData(): void {    // 获取视频的总时长    this.video.addEventListener('loadedmetadata', () => {      this.totalTime = this.formatTime(this.video.duration)    })    // 监听时间发生更改    this.video.addEventListener('timeupdate', () => {      this.currentTime = this.formatTime(this.video.currentTime) // 当前播放的时间    })  }

formatTime 是格式化函数

播放进度条功能

监听鼠标的点击,移动,松开的事件,对视频的播放时间和总事件进行相除,计算百分比。

// app.component.ts    // 进度条鼠标按下  handleProgressDown(event: any): void {    this.videoState.downState = true    this.pause(undefined);    this.videoState.distance = event.clientX + document.documentElement.scrollLeft - this.videoState.leftInit;  }  // 进度条 滚动条移动  handleProgressMove(event: any): void {    if(!this.videoState.downState) return    let distanceX = (event.clientX + document.documentElement.scrollLeft) - this.videoState.leftInit    if(distanceX > this.processWidth) { // 容错处理      distanceX = this.processWidth;    }    if(distanceX < 0) { // 容错处理      distanceX = 0    }    this.videoState.distance = distanceX    this.video.currentTime = this.videoState.distance / this.processWidth * this.video.duration  }  // 进度条 鼠标抬起  handleProgressUp(event: any): void {    this.videoState.downState = false    // 视频播放    this.video.currentTime = this.videoState.distance / this.processWidth * this.video.duration    this.currentTime = this.formatTime(this.video.currentTime)    if(this.videoState.playState) {      this.play(undefined)    }  }

这里需要计算进度条的位置,来获取点击进度条的百分比,之后更新视频的当前播放时间。当然,我们还得有容错处理,比如进度条为负数时候,当前播放时间为0。

声音进度条

我们实现了播放进度条的操作,对声音进度条的实现就很容易上手了。声音进度条也是监听鼠标的点击,移动,松开。不过,这次我们处理的是已知声音 div 的高度。

// app.component.ts    // 声音条 鼠标按下  handleVolProgressDown(event: any) {    this.voiceState.topInit = this.getOffset(this.voiceProOut, undefined).top    this.volProcessHeight = this.voiceProOut.clientHeight    this.voiceState.downState = true //按下鼠标标志    this.voiceState.distance = this.volProcessHeight - (event.clientY + document.documentElement.scrollTop - this.voiceState.topInit)   }  // 声音 滚动条移动  handleVolProgressMove(event: any) {    if(!this.voiceState.downState) return      let disY = this.voiceState.topInit + this.volProcessHeight - (event.clientY + document.documentElement.scrollTop)      if(disY > this.volProcessHeight - 2) { // 容错处理        disY = this.volProcessHeight - 2      }      if(disY < 0) { // 容错处理        disY = 0      }      this.voiceState.distance = disY      this.video.volume = this.voiceState.distance / this.volProcessHeight      this.videoOption.volume = Math.round(this.video.volume * 100)  }  // 声音 鼠标抬起  handleVolProgressUp(event: any) {    this.voiceState.downState = false //按下鼠标标志    let voiceRate =  this.voiceState.distance / this.volProcessHeight    if(voiceRate > 1) {      voiceRate = 1    }    if(voiceRate < 0) {      voiceRate = 0    }    this.video.volume = voiceRate    this.videoOption.volume = Math.round(this.video.volume * 100); // 赋值给视频声音  }

如图:

到此,相信大家对“Angular中如何自定义视频播放器”有了更深的了解,不妨来实际操作一番吧!这里是高防服务器网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

[微信提示:高防服务器能助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

[图文来源于网络,不代表本站立场,如有侵权,请联系高防服务器网删除]
[