您的位置:首页 > 娱乐 > 明星 > 企业管理咨询有限公司是干嘛的_广告传媒公司简介_b2b平台_宁波seo如何做推广平台

企业管理咨询有限公司是干嘛的_广告传媒公司简介_b2b平台_宁波seo如何做推广平台

2024/12/23 10:33:30 来源:https://blog.csdn.net/y2653904/article/details/143955248  浏览:    关键词:企业管理咨询有限公司是干嘛的_广告传媒公司简介_b2b平台_宁波seo如何做推广平台
企业管理咨询有限公司是干嘛的_广告传媒公司简介_b2b平台_宁波seo如何做推广平台

一,定义

avPlayer是鸿蒙提供的开发音视频的组件,播放的流程如下:

监听事件如下:

事件类型说明
stateChange必要事件,监听播放器的state属性改变。
error必要事件,监听播放器的错误信息。
durationUpdate用于进度条,监听进度条长度,刷新资源时长。
timeUpdate用于进度条,监听进度条当前位置,刷新当前时间。
seekDone响应API调用,监听seek()请求完成情况。
当使用seek()跳转到指定播放位置后,如果seek操作成功,将上报该事件。
speedDone响应API调用,监听setSpeed()请求完成情况。
当使用setSpeed()设置播放倍速后,如果setSpeed操作成功,将上报该事件。
volumeChange响应API调用,监听setVolume()请求完成情况。
当使用setVolume()调节播放音量后,如果setVolume操作成功,将上报该事件。
bufferingUpdate用于网络播放,监听网络播放缓冲信息,用于上报缓冲百分比以及缓存播放进度。
audioInterrupt监听音频焦点切换信息,搭配属性audioInterruptMode使用。
如果当前设备存在多个音频正在播放,音频焦点被切换(即播放其他媒体如通话等)时将上报该事件,应用可以及时处理。

二,绘制播放器UI

先看效果图:

 创建一个自定义MusicPlayer组件:

import media from '@ohos.multimedia.media'
import audio from '@ohos.multimedia.audio'
import VolumeUtils from './VolumeUtils'
import { ErrorCallback } from '@ohos.base'@Component
export default struct MusicPlayer {@State volumeImg: string = 'image/pic_volume.png'@State startImg: string = 'image/pic_play.png'@Builder bg() {Rect({ width: "100%", height: "100%" }).radius([[5, 5], [5, 5], [5, 5], [5, 5]]).fill("#F1F111")}aboutToAppear(){}aboutToDisappear(){}build() {RelativeContainer() {Image(this.startImg).width(22.5).height(22.5).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ left: 30 }).id('img_play').onClick( event =>{})Slider({value: this.progressValue,min: 0,max: 100,style: SliderStyle.OutSet }).showTips(false).onChange((value: number, mode: SliderChangeMode) => {}).width('60%').height(4).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: 'img_play', align: HorizontalAlign.End }}).margin({ left: 3}).id('pg_pc')Image(this.volumeImg).width(20).height(20).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: 'pg_pc', align: HorizontalAlign.End }}).margin({ left: 5 }).id('img_volume')Slider({value: this.valumeValue,min: 0,max: 15,style: SliderStyle.OutSet }).showTips(false).onChange((value: number, mode: SliderChangeMode) => {console.info('value:' + value + 'mode:' + mode.toString())}).width('20%').height(4).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: 'img_volume', align: HorizontalAlign.End }}).margin({ left: 3}).id('pg_volume')Text(this.totalDution).fontSize(12).fontColor('#66000000').alignRules({top: { anchor: 'pg_pc', align: VerticalAlign.Bottom },right: { anchor: 'pg_pc', align: HorizontalAlign.End }}).margin({right: 5,top: 3}).id('txt_end_time')Text('/').fontSize(12).fontColor('#66000000').alignRules({top: { anchor: 'pg_pc', align: VerticalAlign.Bottom },right: { anchor: 'txt_end_time', align: HorizontalAlign.Start }}).margin({top: 3}).id('txt_middle_time')Text(this.currentDution).fontSize(12).fontColor('#66000000').alignRules({top: { anchor: 'pg_pc', align: VerticalAlign.Bottom },right: { anchor: 'txt_middle_time', align: HorizontalAlign.Start }}).margin({top: 3}).id('txt_start_time')}.background(this.bg()).width('100%').height(50)}
}

布局组件使用RelativeContainer,参考文章:鸿蒙Harmony-相对布局(RelativeContainer)详解_鸿蒙 relativecontainer-CSDN博客

进度条组件使用Slider,相比于Progress,Slider组件可以拖拽,可以设置滑块样式,使用起来更加方便。

 三,播放音乐

要播放音乐,首先需要创建avPlayer:

createAudioPlayer(): Promise<media.AVPlayer> {return new Promise((resolve, reject) => {media.createAVPlayer().then((audio) => {resolve(audio)}).catch((error:Error)=>{reject(error)})})}

创建完了之后,avPlayer就进入了idle状态,此时可以设置播放器的Url等资源。

 this.createAudioPlayer().then((audio) => {this.avPlayer = audiothis.avPlayer!!.url =this.url}).catch((error:Error)=>{console.error("MusicPlayer:播放器创建失败:"+error.message)})

设置了资源之后,avPlayer进入initialized状态,此时不可以直接播放,通过上面的流程图可以看出来,需要先准备后才可以播放。

prepare() : Promise<boolean> {return new Promise((resolve, reject) => {this.avPlayer?.prepare().then(() => {resolve(true)}).catch((error:Error) => {reject(error)})})}

准备完了之后,就进入到了prepared状态,此时调用play就可以播放了。

play(): Promise<boolean> {return new Promise((resolve, reject) => {this.avPlayer?.play().then(() => {resolve(true)}).catch((error:Error) => {reject(error)})})}

下面我们来简易的做一个播放流程,在aboutToAppear生命周期创建avPlayer,并且设置播放器的Url,在点击播放按钮的时候,准备并播放。

import media from '@ohos.multimedia.media'
import audio from '@ohos.multimedia.audio'
import VolumeUtils from './VolumeUtils'
import { ErrorCallback } from '@ohos.base'@Component
export default struct MusicPlayer {@State url:string =""  //外部传递的UrlavPlayer: media.AVPlayer | undefined = undefined  //播放器@State volumeImg: string = 'image/pic_volume.png'@State startImg: string = 'image/pic_play.png'@Builder bg() {Rect({ width: "100%", height: "100%" }).radius([[5, 5], [5, 5], [5, 5], [5, 5]]).fill("#F1F111")}//创建createAudioPlayer(): Promise<media.AVPlayer> {return new Promise((resolve, reject) => {media.createAVPlayer().then((audio) => {resolve(audio)}).catch((error:Error)=>{reject(error)})})}//准备prepare() : Promise<boolean> {return new Promise((resolve, reject) => {this.avPlayer?.prepare().then(() => {resolve(true)}).catch((error:Error) => {reject(error)})})}//播放play(): Promise<boolean> {return new Promise((resolve, reject) => {this.avPlayer?.play().then(() => {resolve(true)}).catch((error:Error) => {reject(error)})})}aboutToAppear(){this.initVoice()}initVoice(){this.createAudioPlayer().then((audio) => {this.avPlayer = audiothis.avPlayer!!.url =this.url}).catch((error:Error)=>{console.error("MusicPlayer:播放器创建失败:"+error.message)})}startEvent(){this.prepare().then(value=>{this.play().then(result=>{console.error("MusicPlayer:播放成功")}).catch((err:Error)=>{console.error("MusicPlayer:点击播放失败:" + err)})}).catch((err:Error)=>{console.error("MusicPlayer:准备失败:" + err.message)}) }aboutToDisappear(){}build() {RelativeContainer() {Image(this.startImg).width(22.5).height(22.5).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ left: 30 }).id('img_play').onClick( event =>{this.startEvent()})Slider({value: this.progressValue,min: 0,max: 100,style: SliderStyle.OutSet }).showTips(false).onChange((value: number, mode: SliderChangeMode) => {}).width('60%').height(4).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: 'img_play', align: HorizontalAlign.End }}).margin({ left: 3}).id('pg_pc')Image(this.volumeImg).width(20).height(20).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: 'pg_pc', align: HorizontalAlign.End }}).margin({ left: 5 }).id('img_volume')Slider({value: this.valumeValue,min: 0,max: 15,style: SliderStyle.OutSet }).showTips(false).onChange((value: number, mode: SliderChangeMode) => {console.info('value:' + value + 'mode:' + mode.toString())}).width('20%').height(4).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: 'img_volume', align: HorizontalAlign.End }}).margin({ left: 3}).id('pg_volume')Text(this.totalDution).fontSize(12).fontColor('#66000000').alignRules({top: { anchor: 'pg_pc', align: VerticalAlign.Bottom },right: { anchor: 'pg_pc', align: HorizontalAlign.End }}).margin({right: 5,top: 3}).id('txt_end_time')Text('/').fontSize(12).fontColor('#66000000').alignRules({top: { anchor: 'pg_pc', align: VerticalAlign.Bottom },right: { anchor: 'txt_end_time', align: HorizontalAlign.Start }}).margin({top: 3}).id('txt_middle_time')Text(this.currentDution).fontSize(12).fontColor('#66000000').alignRules({top: { anchor: 'pg_pc', align: VerticalAlign.Bottom },right: { anchor: 'txt_middle_time', align: HorizontalAlign.Start }}).margin({top: 3}).id('txt_start_time')}.background(this.bg()).width('100%').height(50)}
}

此时点击播放按钮就可以播放了。

四,暂停播放

 调用暂停播放,进入暂停状态:

  pausePlay(){this.pause().then(value=>{if(value){//图标更改为暂停图标this.startImg ='image/pic_play.png'}else {console.error("MusicPlayer---暂停播放失败:"+value)}}).catch((err:Error)=>{console.error("MusicPlayer---暂停播放失败:"+err.message)})}

监听播放器状态:

this.avPlayer?.on('stateChange',(state)=>{switch (state) {case "initialized":console.info('MusicPlayer-----播放器状态:initialized');this.prepare()breakcase "prepared":console.info('MusicPlayer-----播放器状态:prepared');breakcase 'playing':console.info('MusicPlayer-----播放器状态:playing');break;case 'paused':console.info('MusicPlayer-----播放器状态:paused');break;case 'completed':console.info('MusicPlayer-----播放器状态:completed');break;case 'stopped':console.info('MusicPlayer-----播放器状态:stopped');break;case 'released':console.info('MusicPlayer-----播放器状态:released');break;case 'error':console.info('MusicPlayer-----播放器状态:error');break;default:console.info('MusicPlayer-----播放器状态:default:' + state);break;}
})

开始播放时更改图标:

startPlay(){this.play().then(value=>{if(value){//图标更改为播放图标this.startImg ='image/pic_pause.png'}else {console.error("MusicPlayer---开始播放失败:"+value)}}).catch((err:Error)=>{console.error("MusicPlayer---开始播放失败:"+err.message)})
}

当还没有准备时先准备再播放:

prepareAndPlay(){this.prepare().then(value=>{this.play().then(result=>{if(result){//图标更改为播放图标this.startImg ='image/pic_pause.png'}}).catch((err:Error)=>{console.error("MusicPlayer---点击播放失败:" + err)})}).catch((err:Error)=>{console.error("MusicPlayer---准备失败:" + err.message)})
}

更改开始播放按钮点击事件:

startEvent(){switch (this.avPlayer?.state) {case 'playing'://正在播放 点击暂停播放this.pausePlay()breakcase 'paused'://暂停状态 直接开始播放this.startPlay()breakcase 'prepared'://准备状态 开始播放this.startPlay()breakcase 'initialized'://初始化状态 先准备再播放this.prepareAndPlay()breakcase 'completed'://播放完成状态 直接播放this.startPlay()breakcase 'stopped'://停止状态 先准备再播放this.prepareAndPlay()breakcase 'error'://错误状态this.prepareAndPlay()break}
}

此时播放和暂停就可以了。

五,控制进度条

 定义当前时间和总时间:

@State currentDution: string = "00:00"
@State totalDution: string ="00:00"

监听获取总时长:

this.avPlayer?.on("durationUpdate",totalTime=>{this.totalTime =totalTimethis.totalDution =this.secondsToHMS(Math.floor(totalTime/1000))
})

监听当前播放时长:

this.avPlayer?.on("timeUpdate",time=>{this.currentDution =this.secondsToHMS(Math.floor(time/1000))this.progressValue =(time*100)/this.totalTime
})

转换方法:

secondsToHMS(seconds:number):string {let hours = Math.floor(seconds / 3600);let minutes = Math.floor((seconds % 3600) / 60);let secs = seconds % 60;let result =""if(hours==0){result =minutes.toString().padStart(2, '0')+":"+secs.toString().padStart(2, '0')}else {result = hours.toString().padStart(2, '0')+":"+minutes.toString().padStart(2, '0')+":"+secs.toString().padStart(2, '0')}return result
}

跳转进度:

seek( position: number) {this.avPlayer?.seek(position)
}

当进度条改变时,跳转相应位置:

Slider({value: this.progressValue,min: 0,max: 100,style: SliderStyle.OutSet }).showTips(false).onChange((value: number, mode: SliderChangeMode) => {console.error("MusicPlayer---进度条改变:"+value+"---mode:"+mode)switch (mode){case SliderChangeMode.End:const seek =(this.totalTime*value)/100this.seek(seek)breakcase SliderChangeMode.Begin:breakcase SliderChangeMode.Moving:breakcase SliderChangeMode.Click:const clickSeek =(this.totalTime*value)/100this.seek(clickSeek)break}})

六,完整代码

import media from '@ohos.multimedia.media'
import audio from '@ohos.multimedia.audio'
import VolumeUtils from './VolumeUtils'
import { ErrorCallback } from '@ohos.base'@Component
export default struct MusicPlayer {@State progressValue: number = 0@State valumeValue: number = 0@State currentDution: string = "00:00"@State totalDution: string ="00:00"avPlayer: media.AVPlayer | undefined = undefined@State url:string =""@State volumeImg: string = 'image/pic_volume.png'@State startImg: string = 'image/pic_play.png'@State totalTime: number = 0@Builder bg() {Rect({ width: "100%", height: "100%" }).radius([[5, 5], [5, 5], [5, 5], [5, 5]]).fill("#F1F111")}createAudioPlayer(): Promise<media.AVPlayer> {return new Promise((resolve, reject) => {media.createAVPlayer().then((audio) => {resolve(audio)}).catch((error:Error)=>{reject(error)})})}prepare() : Promise<boolean> {return new Promise((resolve, reject) => {this.avPlayer?.prepare().then(() => {resolve(true)}).catch((error:Error) => {reject(error)})})}play(): Promise<boolean> {return new Promise((resolve, reject) => {this.avPlayer?.play().then(() => {resolve(true)}).catch((error:Error) => {reject(error)})})}pause() : Promise<boolean> {return new Promise((resolve, reject) => {this.avPlayer?.pause().then(() => {resolve(true)}).catch((error:Error) => {reject(error)})})}stop(): Promise<boolean> {return new Promise((resolve, reject) => {this.avPlayer?.stop().then(() => {resolve(true)}).catch((error:Error) => {reject(error)})})}/*** 在音频播放器中寻找指定的位置。** @param {number} position - 要寻找到的位置。* @returns {void}*/seek( position: number) {this.avPlayer?.seek(position)}release() : Promise<boolean> {return new Promise((resolve, reject) => {this.avPlayer?.release().then(() => {resolve(true)}).catch((error:Error) => {reject(error)})})}onError(callback: ErrorCallback) {this.avPlayer?.on("error", callback)}aboutToAppear(){console.info("yhMusicPlayer:url="+this.url)this.initVoice()VolumeUtils.getVolume(audio.AudioVolumeType.MEDIA).then(value=>{this.valumeValue = value}).catch((err: Error) => {console.info("yhMusicPlayer:获取媒体音量失败"+err)})}getPlayerState():string{if(this.avPlayer){return this.avPlayer?.state}else {return 'not init'}}initVoice(){this.createAudioPlayer().then((audio) => {this.avPlayer = audiothis.avPlayer!!.url =this.urlthis.avPlayer?.on('stateChange',(state)=>{switch (state) {case "initialized":console.info('yhMusicPlayer-----播放器状态:initialized');this.prepare()breakcase "prepared":console.info('yhMusicPlayer-----播放器状态:prepared');breakcase 'playing':console.info('yhMusicPlayer-----播放器状态:playing');break;case 'paused':console.info('yhMusicPlayer-----播放器状态:paused');break;case 'completed':console.info('yhMusicPlayer-----播放器状态:completed');break;case 'stopped':console.info('yhMusicPlayer-----播放器状态:stopped');break;case 'released':console.info('yhMusicPlayer-----播放器状态:released');break;case 'error':console.info('yhMusicPlayer-----播放器状态:error');break;default:console.info('yhMusicPlayer-----播放器状态:default:' + state);break;}})this.avPlayer?.on("error", (err)=>{console.error("yhMusicPlayer-------播放器状态失败:"+err.message)})this.avPlayer?.on("durationUpdate",totalTime=>{this.totalTime =totalTimethis.totalDution =this.secondsToHMS(Math.floor(totalTime/1000))})this.avPlayer?.on("timeUpdate",time=>{this.currentDution =this.secondsToHMS(Math.floor(time/1000))this.progressValue =(time*100)/this.totalTime})}).catch((error:Error)=>{console.error("yhMusicPlayer-------播放器创建失败:"+error.message)})}secondsToHMS(seconds:number):string {let hours = Math.floor(seconds / 3600);let minutes = Math.floor((seconds % 3600) / 60);let secs = seconds % 60;let result =""if(hours==0){result =minutes.toString().padStart(2, '0')+":"+secs.toString().padStart(2, '0')}else {result = hours.toString().padStart(2, '0')+":"+minutes.toString().padStart(2, '0')+":"+secs.toString().padStart(2, '0')}return result}startPlay(){this.play().then(value=>{if(value){//图标更改为播放图标this.startImg ='image/pic_pause.png'}else {console.error("yhMusicPlayer---开始播放失败:"+value)}}).catch((err:Error)=>{console.error("yhMusicPlayer---开始播放失败:"+err.message)})}prepareAndPlay(){this.prepare().then(value=>{this.play().then(result=>{if(result){//图标更改为播放图标this.startImg ='image/pic_pause.png'}}).catch((err:Error)=>{console.error("yhMusicPlayer---点击播放失败:" + err)})}).catch((err:Error)=>{console.error("yhMusicPlayer---准备失败:" + err.message)})}pausePlay(){this.pause().then(value=>{if(value){//图标更改为暂停图标this.startImg ='image/pic_play.png'}else {console.error("yhMusicPlayer---暂停播放失败:"+value)}}).catch((err:Error)=>{console.error("yhMusicPlayer---暂停播放失败:"+err.message)})}startEvent(){switch (this.avPlayer?.state) {case 'playing'://正在播放 点击暂停播放this.pausePlay()breakcase 'paused'://暂停状态 直接开始播放this.startPlay()breakcase 'prepared'://准备状态 开始播放this.startPlay()breakcase 'initialized'://初始化状态 先准备再播放this.prepareAndPlay()breakcase 'completed'://播放完成状态 直接播放this.startPlay()breakcase 'stopped'://停止状态 先准备再播放this.prepareAndPlay()breakcase 'error'://错误状态this.prepareAndPlay()break}}aboutToDisappear(){}build() {RelativeContainer() {Image(this.startImg).width(22.5).height(22.5).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ left: 30 }).id('img_play').onClick( event =>{this.startEvent()})Slider({value: this.progressValue,min: 0,max: 100,style: SliderStyle.OutSet }).showTips(false).onChange((value: number, mode: SliderChangeMode) => {console.error("yhMusicPlayer---进度条改变:"+value+"---mode:"+mode)switch (mode){case SliderChangeMode.End:const seek =(this.totalTime*value)/100this.seek(seek)breakcase SliderChangeMode.Begin:breakcase SliderChangeMode.Moving:breakcase SliderChangeMode.Click:const clickSeek =(this.totalTime*value)/100this.seek(clickSeek)break}}).width('60%').height(4).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: 'img_play', align: HorizontalAlign.End }}).margin({ left: 3}).id('pg_pc')Image(this.volumeImg).width(20).height(20).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: 'pg_pc', align: HorizontalAlign.End }}).margin({ left: 5 }).id('img_volume')Slider({value: this.valumeValue,min: 0,max: 15,style: SliderStyle.OutSet }).showTips(false).onChange((value: number, mode: SliderChangeMode) => {switch (mode){case SliderChangeMode.End:VolumeUtils.setVolume(audio.AudioVolumeType.MEDIA,value).then(value=>{console.info("yhMusicPlayer音量调整成功")}).catch((err:Error)=>{console.info("yhMusicPlayer音量调整失败:"+err.message)})breakcase SliderChangeMode.Begin:breakcase SliderChangeMode.Moving:breakcase SliderChangeMode.Click:VolumeUtils.setVolume(audio.AudioVolumeType.MEDIA,value).then(value=>{console.info("yhMusicPlayer音量调整成功")}).catch((err:Error)=>{console.info("yhMusicPlayer音量调整失败:"+err.message)})break}console.info('value:' + value + 'mode:' + mode.toString())}).width('20%').height(4).alignRules({center: { anchor: '__container__', align: VerticalAlign.Center },left: { anchor: 'img_volume', align: HorizontalAlign.End }}).margin({ left: 3}).id('pg_volume')Text(this.totalDution).fontSize(12).fontColor('#66000000').alignRules({top: { anchor: 'pg_pc', align: VerticalAlign.Bottom },right: { anchor: 'pg_pc', align: HorizontalAlign.End }}).margin({right: 5,top: 3}).id('txt_end_time')Text('/').fontSize(12).fontColor('#66000000').alignRules({top: { anchor: 'pg_pc', align: VerticalAlign.Bottom },right: { anchor: 'txt_end_time', align: HorizontalAlign.Start }}).margin({top: 3}).id('txt_middle_time')Text(this.currentDution).fontSize(12).fontColor('#66000000').alignRules({top: { anchor: 'pg_pc', align: VerticalAlign.Bottom },right: { anchor: 'txt_middle_time', align: HorizontalAlign.Start }}).margin({top: 3}).id('txt_start_time')}.background(this.bg()).width('100%').height(50)}
}

 使用:

@Entry
@Component
struct Index {aboutToAppear(){}@Builder bg() {Polygon({width: "100%", height: "100%"}).points([[100, 0], [0, 100], [40, 200], [160, 200], [200, 100]]).fill("#ff1122").stroke("#000000").strokeWidth(10).strokeDashArray([1,2])}build() {Stack({alignContent: Alignment.Center}) {MusicPlayer({url:'http://192.168.31.72/resource/audio/3142adb1eeda4e3fa3d4a26050d176c1.mp3'}).width("90%").height(50)}.width("100%").height("100%")}
}

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com