首页 > 其他分享 >HarmonyOS video 视频播放器

HarmonyOS video 视频播放器

时间:2024-09-13 18:25:08浏览次数:3  
标签:播放器 false width media app height HarmonyOS State video

源码

import { display, window } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  controller: VideoController = new VideoController() //video控制器
  @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X; //播放倍数
  @State curRateName: number = 1; //设置默认播放倍数 用于页面展示文字内容
  @State isAutoPlay: boolean = true //自动播放
  @State isStart: boolean = false //播放状态 开始
  @State showControls: boolean = false//是否展示video自带控件
  @State videoSrc: Resource = $rawfile('video1.mp4') //默认视频路径
  @State previewUri: Resource = $r('app.media.poster1') //默认视频播放预览图片
  @State videoIndex: number = 0; //当前播放视频索引
  @State isFullscreen: boolean = false //是否全屏状态
  // 视频信息列表
  @State VideoList: Array<videoInfo> = [
    new videoInfo($rawfile('video1.mp4'), $r('app.media.poster1')),
    new videoInfo($rawfile('video2.mp4'), $r('app.media.poster2')),
    new videoInfo($rawfile('video3.mp4'), $r('app.media.poster3')),
    new videoInfo($rawfile('video4.mp4'), $r('app.media.poster4'))
  ]
  // 播放倍数list
  @State PlaybackSpeedList: Array<backSpeedInfo> = [
    new backSpeedInfo(0.75, PlaybackSpeed.Speed_Forward_0_75_X),
    new backSpeedInfo(1, PlaybackSpeed.Speed_Forward_1_00_X),
    new backSpeedInfo(1.25, PlaybackSpeed.Speed_Forward_1_25_X),
    new backSpeedInfo(1.75, PlaybackSpeed.Speed_Forward_1_75_X),
    new backSpeedInfo(2, PlaybackSpeed.Speed_Forward_2_00_X)
  ]
  // 获取主窗口实例
  windowStage: window.WindowStage = AppStorage.get('windowStage') as window.WindowStage;
  // 获取主窗口的方式
  mainWin: window.Window = this.windowStage.getMainWindowSync();

  @State videoHeight: string = '27%' //video高度  ,竖屏
  @State isSHowCurRateList: boolean = false //是否显示播放倍数列表
  @State isMute: boolean = false //静音
  @State videoDuration: string = '0' //video总时长
  @State totalTime: number = 0 //进度条总时长
  @State videoDurationEnd: string = '00:00' //进度条倒计时
  @State ProgressTotal: number = 0 //进度条value转换使用的video总时长
  @State ProgressValue: number = 0 //进度条完成进度
  @State ProgressValueFormat: number = 0//进度条完成进度value转换使用的进度条完成
  @State isLandSpace: boolean = false //是否横屏状态 用于设置vide及控件宽度
  @State isShowVideoControls: boolean = false //是否显示自定义控件


  //设置横屏、竖屏
  setWindowFullscreen() {
    // 获取最上层窗口的方式
    window.getLastWindow(getContext(this));
    if (this.isFullscreen) {
      this.videoHeight = '100%'
      //横屏
      this.mainWin.setPreferredOrientation(window.Orientation.LANDSCAPE);
      this.isLandSpace = true
    } else {
      this.videoHeight = '27%'
      //竖屏
      this.mainWin.setPreferredOrientation(window.Orientation.PORTRAIT);
      this.isLandSpace = false
    }
    // 使用display接口获取当前旋转方向,可以放置在监听中持续获取
    display.getDefaultDisplaySync().rotation;
  }

  //点击上下按钮时获取video信息
  getVideo(type: string) {
    this.isStart = false
    this.controller.stop()

    if (type === 'left') {
      this.videoIndex--
    } else {
      this.videoIndex++
    }

    this.VideoList.forEach((item: videoInfo, index) => {
      if (this.videoIndex === index) {
        this.videoSrc = item.videoSrc
        this.previewUri = item.previewUri
      }
    })
    this.isAutoPlay = true
    this.isStart = true
  }

  //计算时间
  getDuration(Time: number) {
    let seconds = Time;
    let hours = Math.floor(seconds / 3600);
    let minutes = Math.floor((seconds % 3600) / 60);
    let remainingSeconds = seconds % 60;

    let hour = hours === 0 ? '' : hours > 9 ? hours : '0' + hours
    let min = minutes === 0 ? '00' : minutes > 9 ? minutes : '0' + minutes
    let seco = remainingSeconds === 0 ? '00' : remainingSeconds > 9 ? remainingSeconds : '0' + remainingSeconds
    let time = hour !== '' ? `${hour}:` : ''
    return `${time}${min}:${seco}`
  }

  //UI界面
  build() {
    Column() {
      Stack() {
        Video({
          src: this.videoSrc, //文件路径
          currentProgressRate: this.curRate, //视频播放倍速。number取值仅支持:0.75,1.0,1.25,1.75,2.0。
          previewUri: this.previewUri, //视频未播放时的预览图片路径
          controller: this.controller, //设置视频控制器,可以控制视频的播放状态。

        })
          .width('100%')
          .height('100%')
          .autoPlay(this.isAutoPlay)
          .controls(this.showControls)
          .onPrepared((e) => {
            this.totalTime = e.duration
            this.videoDuration = this.getDuration(e.duration)
            this.ProgressTotal = this.totalTime
          })
          .onUpdate((e) => {
            this.videoDurationEnd = this.getDuration(Number(this.totalTime) - Number(e.time))
            this.ProgressValue = Number(e.time)
          })
          Column() {
            Row() {
              Text(this.videoDuration)
                .fontSize(12)
                .fontColor('#fff')
                .width(this.isLandSpace ? '5%' : '12%')
                .textAlign(TextAlign.Center)
              Row() {
                Progress({ value: this.ProgressValue, total: this.ProgressTotal, type: ProgressType.Linear })
                  .width('100%')
                  .backgroundColor('rgba(248, 247, 247, 0.51)')
              }
              .width(this.isLandSpace ? '90%' : '76%')

              Text(this.videoDurationEnd)
                .fontSize(12)
                .fontColor('#fff')
                .width(this.isLandSpace ? '5%' : '12%')
                .margin({ left: 5 })
            }
            .width('100%')
            .padding({ top: 5 })

            Row() {
              Flex({ justifyContent: FlexAlign.SpaceBetween }) {
                Row() {
                  Image($r('app.media.previous')).width(25).height(25)
                    .onClick(() => {
                      this.getVideo('left')
                    })
                  Image(!this.isStart ? $r('app.media.start') : $r('app.media.stop')).width(20).height(20)
                    .margin({ left: 10, right: 10 })
                    .onClick(() => {
                      if (!this.isStart) {
                        //开始播放
                        this.controller.start()
                        this.isStart = true
                      } else {
                        //暂停播放,显示当前帧,再次播放时从当前位置继续播放。
                        this.controller.pause()
                        this.isStart = false
                      }
                    })
                  Image($r('app.media.next')).width(20).height(20)
                    .onClick(() => {
                      this.getVideo('right')
                    })
                  Image(!this.isMute ? $r('app.media.no_mute') : $r('app.media.mute')).width(20).height(20)
                    .margin({ left: 10, right: 10 })
                    .onClick(() => {
                      this.isMute = !this.isMute
                    })
                  Text(`${this.curRateName}x`)
                    .width(50)
                    .height(25)
                    .fontSize(14)
                    .fontColor('#fff')
                    .margin({ left: 20, right: 15 })
                    .onClick(() => {
                      this.isSHowCurRateList = !this.isSHowCurRateList
                    })
                  if (this.isSHowCurRateList) {
                    List() {
                      ForEach(this.PlaybackSpeedList, (item: backSpeedInfo) => {
                        ListItem() {
                          Text(`${item.name}`)
                            .fontSize(15)
                            .fontColor('#fff')
                            .textAlign(TextAlign.Center)
                            .width('100%')
                            .onClick(() => {
                              this.curRate = item.curRate
                              this.curRateName = item.name
                              this.isSHowCurRateList = false
                            })
                        }
                      })
                    }
                    .width(40)
                    .height(100)
                    .margin({ left: -70, top: -140 })
                    .backgroundColor('rgba(12, 12, 12, 0.5)')
                    .padding(5)
                  }
                }

                Image(!this.isFullscreen ? $r('app.media.cancel_big_window') : $r('app.media.big_window'))
                  .width(25)
                  .height(25)
                  .onClick(() => {
                    if (!this.isFullscreen) {
                      this.isFullscreen = true
                    } else {
                      this.isFullscreen = false
                    }
                    this.setWindowFullscreen()
                  })
              }
            }
            .width('100%')
            .height('13%')
          }
          .height('100%')
          .padding({ left: 10, right: 10 })
          .justifyContent(FlexAlign.End)
          .visibility(this.isShowVideoControls ? Visibility.Visible : Visibility.None)
      }
      .height(this.videoHeight)
      .onClick(() => {
        this.isShowVideoControls = !this.isShowVideoControls
        console.log('isShowVideoControls',this.isShowVideoControls)
      })
    }
    .height('100%')
  }
}

//为video定义的class类
export class videoInfo {
  videoSrc: Resource;
  previewUri: Resource;

  constructor(videoSrc: Resource, previewUri: Resource) {
    this.videoSrc = videoSrc
    this.previewUri = previewUri
  }
}

export class backSpeedInfo {
  name: number;
  curRate: PlaybackSpeed;

  constructor(name: number, curRate: PlaybackSpeed) {
    this.name = name
    this.curRate = curRate
  }
}

标签:播放器,false,width,media,app,height,HarmonyOS,State,video
From: https://blog.csdn.net/qq_38928048/article/details/142217323

相关文章

  • HarmonyOS开发之Search组件
    在HarmonyOS应用开发中,Search组件提供了丰富的自定义选项,允许开发者根据应用的需求定制搜索栏的外观和行为。本文将通过几个具体的场景来介绍如何使用Search组件的不同属性来自定义搜索栏。场景一:自定义搜索图标为了使搜索栏更加符合应用的设计风格,可以通过searchIcon属性来自......
  • 第一章、HarmonyOS介绍简介
    1.前言欢迎来到鸿蒙应用开发系列教程的第一课,在本单元,你将学习HarmonyOS的基本概念,熟悉HarmonyOS核心技术理念、开发语言、UI框架开发和测试工具,了解应用的上架与分发能力。2.应用开发的机遇、挑战和趋势随着万物互联时代的开启,应用的设备底座将从几十亿手机扩展到数百亿的iot设......
  • 支付宝携手HarmonyOS SDK打造高效便捷的扫码支付体验
    背景在日常的购物转账、生活缴费等在线支付中,用户在正式拉起支付界面前,均需要至少经历一次"识别"+两次"寻找",即识别归属应用、寻找应用、寻找扫码入口,才能完成扫码、付款,每一步都带来不同程度的用户流失。如何将步骤繁琐的扫码支付做到最简化,是优化在线支付体验的关键。策略支付宝......
  • 【软件】Rhythmbox播放器调节音量
    Rhythmbox播放器调节音量零、起因最近换了Ubuntu系统,在写代码时想听歌,故使用Rhythmbox播放器播放一些mp3文件,但同时又要看教程,希望音乐声音小一点,但是找来找去都没有发现Rhythmbox有调音量的地方,官网上有指引:https://help.gnome.org/users/rhythmbox/stable/Usage.html.zh_CN,但......
  • 【代码分析1-视频目标分割AOT-数据处理部分】Associating Objects with Transformers
    AOT代码分析前置阅读代码模块代码分析1静态数据处理1.1引入包1.2继承Dataset类1.3数据初始化1.4获取数据长度1.5获取数据2视频数据处理2.1数据初始化-父类VOSTrain2.2数据初始化-子类DAVIS2017_Train2.3获得数据长度2.4获得数据前置阅读papergithub文献......
  • HarmonyOS开发之Swiper页面布局
    在HarmonyOSNEXT中使用Swiper组件进行页面布局时,为了提供更好的用户体验,我们可以实现一些自定义的动画效果以及自定义指示器。以下是两个具体的实现方案:场景一:Swiper页面支持自定义动画要实现Swiper页面支持自定义动画,我们需要设置Swiper组件的属性,并添加相应的事件处理程序来控制......
  • 常见的web音视频播放器
    1.video-js是否开源:是是否免费:是官网地址:https://videojs.com/特点:支持hls、dash、.mp4、webm等多种视频类型,2.西瓜播放器是否开源:是是否免费:是官网地址:https://v2.h5player.bytedance.com/特点:一款带解析器、能节省流量的HTML5视频播放器。支持播放hls、.m3u8、.flv、......
  • 鸿蒙HarmonyOS Next应用开发实战学习路线
    ✍️作者简介:小北编程(专注于HarmonyOS、Android、Java、Web、TCP/IP等技术方向)......
  • 鸿蒙HarmonyOS装饰器详解
    ✍️作者简介:小北编程(专注于HarmonyOS、Android、Java、Web、TCP/IP等技术方向)......
  • 手机安卓版Python编译器IDE彩色音乐播放器代码
    importpygameimporttkinterastkfromtkinterimportfiledialog初始化pygamepygame.mixer.init()current_song_index=0defplay_music():selected_indices=song_list.curselection()ifselected_indices:globalcurrent_song_indexcurrent_song_index=......