完善音频播放器
This commit is contained in:
parent
4a30c53eda
commit
4af7f394cf
|
|
@ -134,11 +134,6 @@ export class RouterUrls {
|
||||||
*/
|
*/
|
||||||
static readonly VIDEO_PLAYER_PAGE = "pages/video/VideoPlayerPage"
|
static readonly VIDEO_PLAYER_PAGE = "pages/video/VideoPlayerPage"
|
||||||
|
|
||||||
/**
|
|
||||||
* 音频播放页
|
|
||||||
*/
|
|
||||||
static readonly AUDIO_PLAYER_PAGE = "pages/audio/AudioPlayerPage"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图片查看页
|
* 图片查看页
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,8 @@ export struct AudioPlayerDialog {
|
||||||
Image(this.index > 0 ? $r('app.media.ic_last_audio_enable') : $r('app.media.ic_last_audio_disable')).width(20).height(20)
|
Image(this.index > 0 ? $r('app.media.ic_last_audio_enable') : $r('app.media.ic_last_audio_disable')).width(20).height(20)
|
||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
if (this.index > 0) {
|
if (this.index > 0) {
|
||||||
await this.avPlayer!!.stop()
|
await this.avPlayer!!.pause()
|
||||||
|
await this.avPlayer!!.reset()
|
||||||
this.index--
|
this.index--
|
||||||
this.uri = this.mediaList[this.index].uri
|
this.uri = this.mediaList[this.index].uri
|
||||||
this.title = this.mediaList[this.index].name
|
this.title = this.mediaList[this.index].name
|
||||||
|
|
@ -189,7 +190,6 @@ export struct AudioPlayerDialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.visibility(Visibility.None)
|
|
||||||
|
|
||||||
Image(this.isPlaying ? $r('app.media.ic_audio_pause') : $r('app.media.ic_audio_play')).width(30).height(30)
|
Image(this.isPlaying ? $r('app.media.ic_audio_pause') : $r('app.media.ic_audio_play')).width(30).height(30)
|
||||||
.margin({left: 50, right: 50})
|
.margin({left: 50, right: 50})
|
||||||
|
|
@ -206,7 +206,8 @@ export struct AudioPlayerDialog {
|
||||||
.rotate({angle: 180})
|
.rotate({angle: 180})
|
||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
if (this.index < this.mediaList.length - 1) {
|
if (this.index < this.mediaList.length - 1) {
|
||||||
await this.avPlayer!!.stop()
|
await this.avPlayer!!.pause()
|
||||||
|
await this.avPlayer!!.reset()
|
||||||
this.index++
|
this.index++
|
||||||
this.uri = this.mediaList[this.index].uri
|
this.uri = this.mediaList[this.index].uri
|
||||||
this.title = this.mediaList[this.index].name
|
this.title = this.mediaList[this.index].name
|
||||||
|
|
@ -217,7 +218,6 @@ export struct AudioPlayerDialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.visibility(Visibility.None)
|
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.justifyContent(FlexAlign.Center)
|
.justifyContent(FlexAlign.Center)
|
||||||
|
|
|
||||||
|
|
@ -1,237 +0,0 @@
|
||||||
import { TipDialog } from '../../dialog/TipDialog'
|
|
||||||
import { ShareManager } from '../../manager/ShareManager'
|
|
||||||
import { TitleBar } from '../../view/TitleBar'
|
|
||||||
import { ToastUtils } from '../../utils/ToastUtils'
|
|
||||||
import { AppUtil } from '@pura/harmony-utils'
|
|
||||||
import { EventConstants } from '../../common/EventConstants'
|
|
||||||
import { MediaAction, MediaType } from '../../manager/MediaManager'
|
|
||||||
import { media } from '@kit.MediaKit'
|
|
||||||
import { fileIo } from '@kit.CoreFileKit'
|
|
||||||
import { LocalMediaManager } from '../../manager/LocalMediaManager'
|
|
||||||
import { avSessionManager } from '../../manager/AVSessionManager'
|
|
||||||
|
|
||||||
@Entry
|
|
||||||
@ComponentV2
|
|
||||||
struct AudioPlayerPage {
|
|
||||||
@Local title: string = ''
|
|
||||||
@Local uri: string = ''
|
|
||||||
@Local showActions: boolean = false
|
|
||||||
@Local currentTime: number = 0
|
|
||||||
@Local durationTime: number = 0
|
|
||||||
@Local isPlaying: boolean = false
|
|
||||||
|
|
||||||
avPlayer?: media.AVPlayer;
|
|
||||||
|
|
||||||
aboutToAppear(): void {
|
|
||||||
this.initParams()
|
|
||||||
this.initPlayer()
|
|
||||||
}
|
|
||||||
|
|
||||||
onPageHide(): void {
|
|
||||||
if (this.avPlayer) {
|
|
||||||
this.avPlayer.pause()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aboutToDisappear(): void {
|
|
||||||
if (this.avPlayer) {
|
|
||||||
this.avPlayer.release()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initParams() {
|
|
||||||
const params = this.getUIContext().getRouter().getParams() as Record<string, Object>;
|
|
||||||
if (params) {
|
|
||||||
this.title = params.title as string
|
|
||||||
this.uri = params.uri as string;
|
|
||||||
this.showActions = params.showActions as boolean
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async initPlayer() {
|
|
||||||
this.avPlayer = await media.createAVPlayer();
|
|
||||||
// 创建状态机变化回调函数
|
|
||||||
this.setAVPlayerCallback();
|
|
||||||
// 打开相应的资源文件地址获取fd
|
|
||||||
let file = await fileIo.open(this.uri);
|
|
||||||
this.avPlayer.url = 'fd://' + file.fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
formatTime(time: number): string {
|
|
||||||
let minute: number = 0
|
|
||||||
let second: number = 0
|
|
||||||
if (time > 60) {
|
|
||||||
minute = Math.trunc(time / 60)
|
|
||||||
second = time % 60
|
|
||||||
if (minute < 10) {
|
|
||||||
if (second < 10) {
|
|
||||||
return `0${minute}:0${second}`
|
|
||||||
} else {
|
|
||||||
return `0${minute}:${second}`
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (second < 10) {
|
|
||||||
return `${minute}:0${second}`
|
|
||||||
} else {
|
|
||||||
return `${minute}:${second}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
second = time
|
|
||||||
if (second < 10) {
|
|
||||||
return `00:0${second}`
|
|
||||||
} else {
|
|
||||||
return `00:${second}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册avplayer回调函数
|
|
||||||
setAVPlayerCallback() {
|
|
||||||
this.avPlayer!!.on('error', (err) => {
|
|
||||||
console.error(`播放器发生错误,错误码:${err.code}, 错误信息:${err.message}`);
|
|
||||||
// 调用reset重置资源,触发idle状态
|
|
||||||
this.isPlaying = false
|
|
||||||
this.avPlayer!!.reset();
|
|
||||||
avSessionManager.deactivate()
|
|
||||||
})
|
|
||||||
// 状态机变化回调函数
|
|
||||||
this.avPlayer!!.on('stateChange', async (state, reason) => {
|
|
||||||
switch (state) {
|
|
||||||
case 'initialized':
|
|
||||||
console.info('资源初始化完成');
|
|
||||||
// 资源初始化完成,开始准备文件
|
|
||||||
this.avPlayer!!.prepare();
|
|
||||||
break;
|
|
||||||
case 'prepared':
|
|
||||||
console.info('资源准备完成');
|
|
||||||
// 资源准备完成,开始准备文件
|
|
||||||
this.durationTime = Math.trunc(this.avPlayer!!.duration / 1000)
|
|
||||||
this.currentTime = this.avPlayer!!.currentTime;
|
|
||||||
|
|
||||||
await avSessionManager.activate()
|
|
||||||
this.avPlayer!!.play();
|
|
||||||
break;
|
|
||||||
case 'completed':
|
|
||||||
console.info('播放完成');
|
|
||||||
this.isPlaying = false
|
|
||||||
this.avPlayer!!.off('bufferingUpdate')
|
|
||||||
AppStorage.setOrCreate('currentTime', this.durationTime);
|
|
||||||
avSessionManager.deactivate()
|
|
||||||
break;
|
|
||||||
case 'playing':
|
|
||||||
console.info('播放开始');
|
|
||||||
this.isPlaying = true
|
|
||||||
break;
|
|
||||||
case 'released':
|
|
||||||
case 'stopped':
|
|
||||||
case 'error':
|
|
||||||
case 'paused':
|
|
||||||
console.info('播放暂停');
|
|
||||||
this.isPlaying = false
|
|
||||||
avSessionManager.deactivate()
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 时间上报监听函数
|
|
||||||
this.avPlayer!!.on('timeUpdate', (time: number) => {
|
|
||||||
this.currentTime = Math.trunc(time / 1000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
Column() {
|
|
||||||
TitleBar().width('100%')
|
|
||||||
|
|
||||||
RelativeContainer() {
|
|
||||||
Image($r('app.media.ic_audio_thumb'))
|
|
||||||
|
|
||||||
Row() {
|
|
||||||
Image(this.isPlaying ? $r('app.media.ic_player_controls_pause') : $r('app.media.ic_player_controls_play'))
|
|
||||||
.width(20)
|
|
||||||
.height(20)
|
|
||||||
.margin({ right: 20 })
|
|
||||||
.onClick(async () => {
|
|
||||||
if (this.isPlaying) {
|
|
||||||
this.avPlayer!!.pause()
|
|
||||||
} else {
|
|
||||||
await avSessionManager.activate()
|
|
||||||
this.avPlayer!!.play()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
Text(this.formatTime(this.currentTime)).width(35).fontColor(Color.White).fontSize(12)
|
|
||||||
Slider({
|
|
||||||
value: this.currentTime,
|
|
||||||
min: 0,
|
|
||||||
max: this.durationTime
|
|
||||||
})
|
|
||||||
.blockColor(Color.White)
|
|
||||||
.trackColor($r('app.color.color_60ffffff'))
|
|
||||||
.onChange((value: number, mode: SliderChangeMode) => {
|
|
||||||
this.avPlayer!!.seek(value * 1000, 2); // 设置视频播放的进度跳转到value处
|
|
||||||
this.currentTime = value;
|
|
||||||
})
|
|
||||||
.layoutWeight(1)
|
|
||||||
Text(this.formatTime(this.durationTime)).width(35).fontColor(Color.White).fontSize(12)
|
|
||||||
}
|
|
||||||
.opacity(0.8)
|
|
||||||
.width("100%")
|
|
||||||
.padding({ left: 30, right: 30 })
|
|
||||||
.margin({ bottom: this.showActions ? 0 : 50})
|
|
||||||
.alignRules({
|
|
||||||
bottom: { anchor: '__container__', align: VerticalAlign.Bottom }
|
|
||||||
})
|
|
||||||
}.layoutWeight(1)
|
|
||||||
|
|
||||||
Row() {
|
|
||||||
Column() {
|
|
||||||
Image($r('app.media.ic_action_share')).width(50).height(50)
|
|
||||||
Text('转发').fontSize(12).fontColor($r('app.color.color_50ffffff')).margin({ top: 13 })
|
|
||||||
}
|
|
||||||
.id('btn_share')
|
|
||||||
.alignRules({
|
|
||||||
right: { anchor: '__container__', align: HorizontalAlign.Center }
|
|
||||||
})
|
|
||||||
.margin({ right: 40 })
|
|
||||||
.onClick(() => {
|
|
||||||
ShareManager.shareFile(this.uri)
|
|
||||||
})
|
|
||||||
|
|
||||||
Column() {
|
|
||||||
Image($r('app.media.ic_action_delete')).width(50).height(50)
|
|
||||||
Text('删除').fontSize(12).fontColor($r('app.color.color_50ffffff')).margin({ top: 13 })
|
|
||||||
}
|
|
||||||
.id('btn_delete')
|
|
||||||
.alignRules({
|
|
||||||
left: { anchor: '__container__', align: HorizontalAlign.Center },
|
|
||||||
})
|
|
||||||
.margin({ left: 40 })
|
|
||||||
.onClick(() => {
|
|
||||||
this.avPlayer!!.pause()
|
|
||||||
TipDialog.show(this.getUIContext(), {
|
|
||||||
title: '提示', content: '确定删除该音频?', callback: {
|
|
||||||
confirm: () => {
|
|
||||||
fileIo.unlink(this.uri)
|
|
||||||
.then(() => {
|
|
||||||
ToastUtils.show('删除成功')
|
|
||||||
LocalMediaManager.delete(this.title)
|
|
||||||
AppUtil.getContext().eventHub.emit(EventConstants.MediaActionEvent, MediaType.AUDIO, MediaAction.DELETE)
|
|
||||||
this.getUIContext().getRouter().back()
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
ToastUtils.show('删除失败, 请到文件管理中手动删除')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
.height(200)
|
|
||||||
.margin({ top: 10 })
|
|
||||||
.visibility(this.showActions ? Visibility.Visible : Visibility.None)
|
|
||||||
}
|
|
||||||
.width('100%')
|
|
||||||
.height('100%')
|
|
||||||
.backgroundColor($r('app.color.window_background'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -23,13 +23,12 @@ import { AudioRecordPage } from './record/AudioRecordPage';
|
||||||
|
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
export struct MinePage {
|
export struct MinePage {
|
||||||
@Local showChallenge: boolean = false;
|
|
||||||
@Local showShare: boolean = false;
|
|
||||||
@Local isLogin: boolean = LoginManager.isLogin();
|
@Local isLogin: boolean = LoginManager.isLogin();
|
||||||
@Local userinfo?: UserEntity;
|
@Local userinfo?: UserEntity;
|
||||||
@Local diamondInfo?: DiamondDetailEntity
|
@Local diamondInfo?: DiamondDetailEntity
|
||||||
@Local currentIndex: number = 0;
|
@Local currentIndex: number = 0;
|
||||||
@Local tabBarModifier: CommonModifier = new CommonModifier()
|
@Local tabBarModifier: CommonModifier = new CommonModifier()
|
||||||
|
@Local menuList: Array<MenuEntity> = []
|
||||||
|
|
||||||
private viewModel: MineViewModel = new MineViewModel(this.getUIContext());
|
private viewModel: MineViewModel = new MineViewModel(this.getUIContext());
|
||||||
|
|
||||||
|
|
@ -41,6 +40,7 @@ export struct MinePage {
|
||||||
@Monitor('viewModel.userEntity')
|
@Monitor('viewModel.userEntity')
|
||||||
onUserinfoChange(monitor: IMonitor) {
|
onUserinfoChange(monitor: IMonitor) {
|
||||||
this.userinfo = monitor.value()?.now as UserEntity;
|
this.userinfo = monitor.value()?.now as UserEntity;
|
||||||
|
this.menuList = mineMenuList().convertToArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Monitor('viewModel.wxService')
|
@Monitor('viewModel.wxService')
|
||||||
|
|
@ -287,7 +287,7 @@ export struct MinePage {
|
||||||
Text('常用工具').fontColor($r('app.color.color_212226')).fontSize(16).fontWeight(FontWeight.Medium).margin({top: 20})
|
Text('常用工具').fontColor($r('app.color.color_212226')).fontSize(16).fontWeight(FontWeight.Medium).margin({top: 20})
|
||||||
|
|
||||||
Grid() {
|
Grid() {
|
||||||
ForEach(mineMenuList().convertToArray(), (item: MenuEntity) => {
|
ForEach(this.menuList, (item: MenuEntity) => {
|
||||||
GridItem() {
|
GridItem() {
|
||||||
Column() {
|
Column() {
|
||||||
Image(item.icon)
|
Image(item.icon)
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@
|
||||||
"pages/main/mine/setting/account/BindAccountPage",
|
"pages/main/mine/setting/account/BindAccountPage",
|
||||||
"pages/main/mine/setting/account/ManageAccountPage",
|
"pages/main/mine/setting/account/ManageAccountPage",
|
||||||
"pages/video/VideoPlayerPage",
|
"pages/video/VideoPlayerPage",
|
||||||
"pages/audio/AudioPlayerPage",
|
|
||||||
"pages/photo/PhotoViewPage"
|
"pages/photo/PhotoViewPage"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue