首页前端开发其他前端知识Angular中如何实现自定义Video

Angular中如何实现自定义Video

时间2024-03-28 03:20:03发布访客分类其他前端知识浏览1486
导读:这篇文章给大家分享的是“Angular中如何实现自定义Video”,文中的讲解内容简单清晰,对大家认识和了解都有一定的帮助,对此感兴趣的朋友,接下来就跟随小编一起了解一下“Angular中如何实现自定义Video”吧。 最...
这篇文章给大家分享的是“Angular中如何实现自定义Video”,文中的讲解内容简单清晰,对大家认识和了解都有一定的帮助,对此感兴趣的朋友,接下来就跟随小编一起了解一下“Angular中如何实现自定义Video”吧。


 


最近自己在网上看到别人使用 vue 进行自定义 video 的操作。加上不久前实现了 angular 自定义 video 的相关需求, 遂来记录一下,作为交流思考。

实现的功能如下:

  • 播放 / 停止
  • 快退 / 快进 / 倍速
  • 声音开 / 声音关
  • 进入全屏 / 退出全屏
  • 进入画中画 / 退出画中画 【安卓平板不支持,不建议使用】
  • 经过时长 / 总时长
  • 播放进度条功能:支持点击,拖拽进度
  • 声音进度条功能:支持点击,拖拽进度

如图:

下面我们来一一实现:

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

!-- 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);
 // 赋值给视频声音
}
    

如图:

效果演示

完成了上面的内容,我们以一个 gif 图来展示效果:

全屏,声音和画中画比较难截图,Gif 上体现不来


关于“Angular中如何实现自定义Video”的内容就介绍到这,感谢各位的阅读,相信大家对Angular中如何实现自定义Video已经有了进一步的了解。大家如果还想学习更多知识,欢迎关注网络,小编将为大家输出更多高质量的实用文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Angular中如何实现自定义Video
本文地址: https://pptw.com/jishu/654665.html
HTML5中怎么实现图片淡入淡出的展示效果 用HTML5生成验证码的思路和代码是什么

游客 回复需填写必要信息