Maison  >  Article  >  interface Web  >  Comment personnaliser le lecteur vidéo dans Angular

Comment personnaliser le lecteur vidéo dans Angular

青灯夜游
青灯夜游original
2022-04-28 10:39:562812parcourir

Comment personnaliser les opérations vidéo ? Lecteur vidéo personnalisé ? L'article suivant vous présentera comment personnaliser les opérations vidéo dans Angular. J'espère qu'il vous sera utile !

Comment personnaliser le lecteur vidéo dans Angular

L'article précédent est Implémentation du contrôle des autorisations pour les projets angulaires. Récemment, j'ai vu d'autres personnes utiliser vue pour personnaliser des vidéo en ligne. De plus, les exigences associées à la personnalisation angulaire de la vidéo ont été mises en œuvre il n'y a pas longtemps, je vais donc l'enregistrer comme un échange de pensées. [Recommandations du didacticiel associé : "vue 进行自定义 video 的操作。加上不久前实现了 angular 自定义 video 的相关需求, 遂来记录一下,作为交流思考。【相关教程推荐:《angular教程》】

实现的功能如下:

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

如图:

Comment personnaliser le lecteur vidéo dans Angular

下面我们来一一实现:

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

<!-- app.component.html -->

<div class="video-page">
  <div class="video-tools">
    <button nz-button nzType="primary" (click)="play(&#39;btn&#39;)" style="margin-right: 12px;">播放 ✅</button>
    <button nz-button nzType="primary" (click)="pause(&#39;btn&#39;)">暂停 ✅</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&#39;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
}

Comment personnaliser le lecteur vidéo dans Angular

声音开 / 声音关

声音的开关使用 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(&#39;loadedmetadata&#39;, () => {
    this.totalTime = this.formatTime(this.video.duration)
  })
  // 监听时间发生更改
  this.video.addEventListener(&#39;timeupdate&#39;, () => {
    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); // 赋值给视频声音
}

如图:

Comment personnaliser le lecteur vidéo dans Angular

效果演示

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

Comment personnaliser le lecteur vidéo dans Angular

全屏,声音和画中画比较难截图,GifTutoriel angulaire

"]🎜🎜Les fonctions implémentées sont les suivantes :🎜
  • Lecture/arrêt
  • Retour rapide/avance rapide/double vitesse
  •  Son activé/Son désactivé
  • Entrer en plein écran/Quitter le plein écran
  • Entrer l'image dans l'image/Quitter l'image dans l'image [Les tablettes Android ne sont pas prises en charge et sont non recommandé]
  • Durée écoulée/durée totale
  • Fonction de barre de progression de lecture : prend en charge la progression en cliquant et en faisant glisser
  • Fonction de barre de progression du son : prend en charge la progression en cliquant et en faisant glisser
🎜 Comme le montre l'image : 🎜🎜Comment personnaliser le lecteur vidéo dans Angular 🎜🎜Implémentons-le un par un : 🎜🎜L'accent ici n'est pas mis sur la mise en page, définissons-la simplement : 🎜rrreee
🎜conception de fourmi angulaire est utilisé ici, et j'ai déjà écrit un article connexe, les lecteurs qui ne le connaissent pas peuvent aller sur Angulaire combiné développement rapide NG-ZORRO🎜🎜

Play/Stop

🎜Ici, appelez directement la méthode objet video play() et pause() :🎜rrreee🎜Le play et personnalisés Les méthodes pause ajoutent ici un indicateur, comme suit. Le contrôle de la barre de progression dont il sera question ci-dessous est utile. Le code ci-dessus peut être plus concis et les lecteurs peuvent l'écrire sous forme d'abréviations. 🎜

Retour rapide/avance rapide/double vitesse

🎜Il existe différentes options pour le retour rapide, l'avance rapide et la double vitesse, qui peuvent être contrôlé via des paramètres Livrer : 🎜rrreee🎜Comment personnaliser le lecteur vidéo dans Angular 🎜

Son activé/Son désactivé

🎜Pour activer et désactiver le son, utilisez l'attribut muet de video  : 🎜rrreee

Entrer en plein écran/sortir du plein écran

🎜Le fonctionnement du plein écran est également très simple. Utilisez webkitRequestFullScreen. 🎜rrreee
🎜Après le plein écran, appuyez sur esc pour quitter le plein écran🎜

Entrer l'image dans l'image/quitter l'image- in-picture

🎜l'image dans l'image équivaut à une vidéo qui rétrécit dans une fenêtre contextuelle~ 🎜rrreee🎜Définissez le style de la vidéo afin qu'elle ne paraisse pas intrusive...🎜

Durée écoulée/Durée totale

🎜Enregistrer la vidéo La durée totale et la durée de lecture actuelle de la vidéo. Lorsque nous arrivons au composant, nous obtenons les méta-informations de la vidéo et obtenons la durée totale pendant le processus de lecture vidéo, nous mettons à jour la durée actuelle. 🎜rrreee
🎜formatTime est la fonction de formatage🎜

Fonction de barre de progression de lecture

🎜Écoutez le clic, le déplacement, le relâchementÉvénements, divisez la durée de lecture vidéo et le nombre total d'événements pour calculer le pourcentage. 🎜rrreee🎜Ici, vous devez calculer la position de la barre de progression pour obtenir le pourcentage de clics sur la barre de progression, puis mettre à jour la durée de lecture actuelle de la vidéo. Bien entendu, nous devons également disposer d'un traitement de tolérance aux pannes. Par exemple, lorsque la barre de progression est négative, le temps de lecture actuel est de 0. 🎜

Barre de progression du son

🎜Nous avons implémenté le fonctionnement de la barre de progression de lecture, et il est facile de démarrer avec la mise en œuvre de la barre de progression du son. La barre de progression du son surveille également le clic, le déplacement et le relâchement de la souris. Cependant, cette fois nous avons affaire à la hauteur d'un son connu div. 🎜rrreee🎜Comme le montre l'image : 🎜🎜 Comment personnaliser le lecteur vidéo dans Angular 🎜

Démonstration de l'effet

🎜Après avoir terminé le contenu ci-dessus, nous utilisons une image gif pour montrer l'effet : 🎜 🎜Comment personnaliser le lecteur vidéo dans Angular🎜
🎜Le plein écran, le son et l'image dans l'image sont difficiles à capturer et ne peuvent pas être reflétés sur Gif🎜

Pour le code détaillé, veuillez vous rendre sur video-ng pour l'obtenir.

【Fin】

Pour plus de connaissances liées à la programmation, veuillez visiter : Introduction à la programmation ! !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn