From d20d29bc859f35d7e6a14e9943aba1b20dc68285 Mon Sep 17 00:00:00 2001 From: m00472246 Date: Mon, 17 Jan 2022 15:35:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0js-apis-media.md=E5=92=8Caudi?= =?UTF-8?q?o-playback.md=20Signed-off-by:=20m00472246=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: m00472246 Change-Id: I0432bc60aa4b4b4bec295fe589c18a815b0a1a8c Signed-off-by: m00472246 --- zh-cn/application-dev/media/audio-playback.md | 290 ++++++---- .../media/figures/zh-ch_image_20220117.jpg | Bin 0 -> 68975 bytes .../reference/apis/js-apis-media.md | 518 ++++++++++++++---- 3 files changed, 573 insertions(+), 235 deletions(-) create mode 100644 zh-cn/application-dev/media/figures/zh-ch_image_20220117.jpg diff --git a/zh-cn/application-dev/media/audio-playback.md b/zh-cn/application-dev/media/audio-playback.md index 2afa827c57f..9a385d90763 100644 --- a/zh-cn/application-dev/media/audio-playback.md +++ b/zh-cn/application-dev/media/audio-playback.md @@ -1,131 +1,179 @@ # 音频播放开发指导 -- [场景介绍](#场景介绍) -- [接口说明](#接口说明) - ## 场景介绍 音频播放的主要工作是将音频数据转码为可听见的音频模拟信号并通过输出设备进行播放,同时对播放任务进行管理。 **图1** 音频播放状态机 -![zh-cn_image_0000001182608857](figures/zh-cn_image_0000001182608857.png) - - -## 接口说明 - -**表1** media - -| 接口名 | 描述 | -| -------- | -------- | -| media.createAudioPlayer() | 创建AudioPlayer实例。 | -| AudioPlayer | 提供音频播放相关功能,具体见表 音频播放相关的interface AudioPlayer。 | - -**表2** 音频播放相关的interface **AudioPlayer** - -| 接口名 | 描述 | -| -------- | -------- | -| release() | 释放音频资源。 | -| play() | 开始播放音频源。 | -| pause() | 暂停播放。 | -| stop() | 停止播放。 | -| reset()7+ | 重置播放音频源。 | -| setVolume(vol: number) | 改变音频播放音量 | -| seek(timeMs: number) | 改变播放位置。 | -| src:string | 音频播放的媒体URI。 | -| state:AudioState | 播放的状态属性。 | -| currentTime:number | 音频的当前播放位置。 | -| duration:number | 音频播放的时长(当数据源不支持改变播放位置时返回-1, 比如实时流媒体场景)。 | -| loop:boolean | 音频的循环播放属性。 | -| on('play', function callback) | 订阅音频播放开始事件。 | -| on('pause', function callback) | 订阅音频播放暂停事件。 | -| on('stop', function callback) | 订阅音频播放停止事件。 | -| on('reset', function callback) | 订阅音频播放重置事件。 | -| on('finish',function callback) | 订阅音频播放结束事件。 | -| on('error', function callback) | 订阅音频播放错误事件。 | -| on('dataload', function callback) | 订阅音频播放加载数据事件。 | -| on('volumeChange', function callback) | 订阅音频播放音量变化事件。 | -| on('timeUpdate', function callback) | 订阅音频播放进度改变事件。 | - - -1. 创建音频播放器。 - ``` - import media from '@ohos.multimedia.media'; - var player = media.createAudioPlayer(); - ``` - -2. 设置消息订阅事件。 - ``` - player.on('play', (err, action) => { - if (err) { - console.error('Error returned in the play() callback.'); - return; - } - console.info('Current player duration: '+ player.duration); - console.info('Current player time: ' + player.currentTime); - console.info('Current player status: '+player.state); - console.info('Pause MP3'); - player.pause(); - }); - player.on('pause', (err, action) => { - if (err) { - console.error('Error returned in the pause() callback.'); + +![zh-ch_image_20220117](figures/zh-ch_image_20220117.jpg) + +## 音频播放开发步骤 + +详细API含义可参考:[js-apis-media.md](../reference/apis/js-apis-media.md) + +### 全流程场景 + +包含流程:创建实例,设置uri,播放音频,跳转播放位置,设置音量,暂停播放,获取轨道信息,停止播放,重置,释放资源等流程。 + +AudioPlayer支持的src媒体源输入类型可参考:[src属性说明](../reference/apis/js-apis-media.md#audioplayer_属性) + +```js +function SetCallBack(audioPlayer) { + audioPlayer.on('dataLoad', () => { //设置'dataLoad'事件回调,src属性设置成功后,触发此回调 + console.info('audio set source success'); + //播放界面可切换至已准备好,可点击播放按钮进行播放状态 + }); + audioPlayer.on('play', () => { //设置'play'事件回调 + console.info('audio play success'); + //将播放按钮切换至可暂停状态 + }); + audioPlayer.on('pause', () => { //设置'pause'事件回调 + console.info('audio pause success'); + //将播放按钮切换至可播放状态 + }); + audioPlayer.on('stop', () => { //设置'stop'事件回调 + console.info('audio stop success'); + //播放停止,播放进度条归零,播放按钮切换至可播放状态 + }); + audioPlayer.on('reset', () => { //设置'reset'事件回调 + console.info('audio reset success'); + //需重新设置src属性后,可继续播放其他音频 + }); + audioPlayer.on('timeUpdate', (seekDoneTime) => {//设置'timeUpdate'事件回调 + if (typeof(seekDoneTime) == 'undefined') { + console.info('audio seek fail'); return; - } - console.info('Current player status: ' + player.state); - console.info('Current player time: ' + player.currentTime); - player.seek(30000); // Seek for 30 seconds. - }); - player.on('stop', (err, action) => { - if (err) { - console.error('Error returned in the stop() callback.'); - return; - } - console.info('stop callback invoked. State:' + player.state); - player.reset(); - }); - player.on('dataLoad', (err, action) => { - if (err) { - console.error('Error returned in the dataLoad() callback.'); - return; - } - console.info('dataLoad callback invoked. Current time: ' + player.currentTime); - console.info('Duration of the source:' + player.duration); - player.play(); - }); - player.on('reset', (err, action) => { - if (err) { - console.error('Error returned in the reset() callback.'); - return; - } - console.info('reset callback invoked.'); - player.release(); - }); - player.on('finish', (err, action) => { - if (err) { - console.error('Error returned in the finish() callback.'); - return; } - console.info('finish callback invoked.'); - }); - player.on('timeUpdate', (seekTime, action) => { - console.info('Seek time: ' + seekTime); - console.info('Current player time: ' + player.currentTime); - var newTime = player.currentTime; - if(newTime == 30000) { - console.info('Seek succeeded. New time: ' + newTime); - } else { - console.error('Seek failed: ', + newTime); + console.info('audio seek success, and seek time is ' + seekDoneTime); + //播放进度条更新到seek对应的位置 + }); + audioPlayer.on('volumeChange', () => { //设置'volumeChange'事件回调 + console.info('audio volumeChange success'); + //更新音量显示 + }); + audioPlayer.on('finish', () => { //设置'finish'事件回调,播放完成触发 + console.info('audio play finish'); + }); + audioPlayer.on('error', (error) => { //设置'error'事件回调 + console.info(`audio error called, errName is ${error.name}`); + console.info(`audio error called, errCode is ${error.code}`); + console.info(`audio error called, errMessage is ${error.message}`); + }); +} + +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('audio key is ' + item); + console.info('audio value is ' + property); + } +} + +//1、创建实例 +let audioPlayer = media.createAudioPlayer(); +SetCallBack(audioPlayer); //设置事件回调 +//2、用户选择音频,设置uri +audioPlayer.src = 'file:///data/data/ohos.xxx.xxx/files/test.mp3'; //设置src属性,并触发'dataLoad'事件回调 +//3、播放音频 +audioPlayer.play(); //需等待'dataLoad'事件回调完成后,才可调用play进行播放,触发'play'事件回调 +//4、跳转播放位置 +audioPlayer.seek(30000); //触发'timeUpdate'事件回调,seek到30000ms处播放 +//5、设置音量 +audioPlayer.setVolume(0.5); //触发'volumeChange'事件回调 +//6、暂停播放 +audioPlayer.pause(); //触发'pause'事件回调,暂停播放 +//7、获取轨道信息 +audioPlayer.getTrackDescription((error, arrlist) => { //通过回调方式获取音频轨道信息 + if (typeof (arrlist) != 'undefined') { + for (let i = 0; i < arrlist.length; i++) { + printfDescription(arrlist[i]); } - player.stop(); - }); - player.on('error', (err) => { - console.error('Player error: ${err.message}'); - }); - ``` - -3. 启动播放。 - ``` - var audioSourceMp3 = 'file://test.mp3'; - player.src = audioSourceMp3; - player.loop = true; - ``` + } else { + console.log(`audio getTrackDescription fail, error:${error.message}`); + } +}); +//8、停止播放 +audioPlayer.stop(); //触发'stop'事件回调 +//9、重置播放资源 +audioPlayer.reset(); //触发'reset'事件回调后,重新设置src属性,可完成切歌 +//10、释放资源 +audioPlayer.release(); //audioPlayer资源被销毁 +audioPlayer = undefined; +``` + +### 正常播放场景 + +```js +function SetCallBack(audioPlayer) { + audioPlayer.on('dataLoad', () => { //设置'dataLoad'事件回调,src属性设置成功后,触发此回调 + console.info('audio set source success'); + audioPlayer.play(); //调用play方法开始播放,触发'play'事件回调 + }); + audioPlayer.on('play', () => { //设置'play'事件回调 + console.info('audio play success'); + }); + audioPlayer.on('finish', () => { //设置'finish'事件回调,播放完成触发 + console.info('audio play finish'); + audioPlayer.release(); //audioPlayer资源被销毁 + audioPlayer = undefined; + }); +} + +let audioPlayer = media.createAudioPlayer(); //创建一个音频播放实例 +SetCallBack(audioPlayer); //设置事件回调 +/* 用户选择音频,设置uri */ +audioPlayer.src = 'file:///data/data/ohos.xxx.xxx/files/test.mp3'; //设置src属性,并触发'dataLoad'事件回调 +``` + +### 切歌场景 + +```js +function SetCallBack(audioPlayer) { + audioPlayer.on('dataLoad', () => { //设置'dataLoad'事件回调,src属性设置成功后,触发此回调 + console.info('audio set source success'); + audioPlayer.play(); //调用play方法开始播放,触发'play'事件回调 + }); + audioPlayer.on('play', () => { //设置'play'事件回调 + console.info('audio play success'); + }); + audioPlayer.on('finish', () => { //设置'finish'事件回调,播放完成触发 + console.info('audio play finish'); + audioPlayer.release(); //audioPlayer资源被销毁 + audioPlayer = undefined; + }); +} + +let audioPlayer = media.createAudioPlayer(); //创建一个音频播放实例 +SetCallBack(audioPlayer); //设置事件回调 +/* 用户选择音频,设置uri */ +audioPlayer.src = 'file:///data/data/ohos.xxx.xxx/files/test.mp3'; //设置src属性,并触发'dataLoad'事件回调 +/* 播放一段时间后,下发切歌指令 */ +audioPlayer.reset(); +audioPlayer.src = 'file:///data/data/ohos.xxx.xxx/files/next.mp3'; +``` + +### 单曲循环场景 + +```js +function SetCallBack(audioPlayer) { + audioPlayer.on('dataLoad', () => { //设置'dataLoad'事件回调,src属性设置成功后,触发此回调 + console.info('audio set source success'); + audioPlayer.play(); //调用play方法开始播放,触发'play'事件回调 + }); + audioPlayer.on('play', () => { //设置'play'事件回调 + console.info('audio play success'); + }); + audioPlayer.on('finish', () => { //设置'finish'事件回调,播放完成触发 + console.info('audio play finish'); + audioPlayer.release(); //audioPlayer资源被销毁 + audioPlayer = undefined; + }); +} + +let audioPlayer = media.createAudioPlayer(); //创建一个音频播放实例 +SetCallBack(audioPlayer); //设置事件回调 +/* 用户选择音频,设置uri */ +audioPlayer.src = 'file:///data/data/ohos.xxx.xxx/files/test.mp3'; //设置src属性,并触发'dataLoad'事件回调 +audioPlayer.loop = true; //设置循环播放属性 +``` \ No newline at end of file diff --git a/zh-cn/application-dev/media/figures/zh-ch_image_20220117.jpg b/zh-cn/application-dev/media/figures/zh-ch_image_20220117.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bc56b9d8395873193bbad2b3faf7340c6728af60 GIT binary patch literal 68975 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

q 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 |#vTjx#pRQQlb-vZzT|J-I@b}Nf6kDX1 z3KgGBN{m0zaOQ5xi1^I9xdn0H+1|S>lss}dnt@Tp7SWuA{vSxg`Z5fYwp6}fsUbR^ zRLYv$_?4gRm5t9>*Sq^^5L&AFmz?TSA$gf+>`oz@(VtvWduUogB^-0pQ%|%(LWtvV zb}IQnsPJo7>mSb;1SV2OS6lx)JvZU+@+oW0@?OvRgu3(G)-H@ub{Yq!mI92Z;~#p@ zq12|lWEO`dD9)S;^;y|`-gHJvJ-*jfGc@YtgGcOUj&>uNkyZ!Dt5Hbnt^@ z67VS^puq4FI=Ir^-`uy6=c`;Z8RBZqpqL?@io$GcL54a#T=yZ(5O=N{>NL6T3hMRl zYC^-*hm#T=FC-(QH%D@OR}QRbmS_H)WRYWjd?9{9`5Lu*7yDmMQ}v+i1UD+rxvhUb z3>p0VcJ8~Y<{v+;w%WgEEQ&7HpL#DLrd|k!q(r=-j<2?{>TlrR z5^3~T|Dn&WA-9<54jDEtW`61lp&Z*9ob%o5>Ad)2V8}`}V*3#l`|G~W>x+F_>DRm| z>|N^B{Rztt*Mf_EYwLW7bXDShe}3Acx;__*46OwnwgM4-=$N9Wp$UT=_$^IkDh6Gn z8BCCM-e#iB0YSweZfybEQ}M!6?zYhAWE2oEewo>TG3ZzwM86w3|2H@PvN+9j|s z6K#i$@2P#(V)5chTJ`ZR+o=nm<$i_spY+W7_{nT?s794(H*w<#y8d{ZoR2v z?%<)kYP=!exS>xi#Yqvn=ntwR|7=$SEYFZKv z15h6XWuk3!lVUh890y{1aa5|Zvhqy15);T`%3+U_Kvm!dl<_S*tUOFHOf|wGv%fx& zdf0lYFkH2|{|rS7wb5@&cS^E@%oZ1A1z1pIW=kHWKv(+Tc9id_^Wrn09B>=nv4A75 z!ZtB=6dD|mK?zP@F>isTm}hOS7rFr*Av?ml&0-w-X*_4uuRnk$ICDT?GkLMK#;OG& zZ8T2R-@m3iD4E2mII(1|ChgympTw@*mgn2KQq67x6H=Kk-$ke|c^ORrsk6)84t2F<&5W2V_|pIGW^xalFxa|&g`K*OmN4~w%+lB+HfFB^A;#vs(g7!lsc^f zb59*-)?jRe4wSAdHw~kL4`2i+#XTbqWuyK5eM5el;Q%Z(W5Ntl_s-cEsd5@j)F=s2 z__P8J$?)TuRKJVn@88Z=*1}*eOODo8V*h%Cq{5`*W-A=#QI2Zo`BHgH0KqRndq4+$ zC3(ECc5nwukdun%;9%D^2uBEn@xh`i_wPgb1n4t5oC(2N8MlGhpeXY-+3`D|;VRHU z(q|%My?TmYisrw~_PFBl71w$^KjLSVvstCJCV3hd3**X1fxzPp*2d!i5qJqJo=rH^ z#_*6}z9c}kFFygPmrE3P9&<2g0M$*TU&X>8r^Xs67KR$dFcV~UlMAm+L6FvCqacjW zXAi9*^QvV>;n7)0nd!Ome`8u0Lh)kg8qxA*R6zTnKmG*#flFw+Ur?H_9NB<>y(4V< zxh`O{H);Cq+e_nLo}Na?7UF9wJZZ|(gyH|ZW>PtJHx1^1<;i@;&$hL+s4Vc}tka>x zNmqoudZle6TfMS<2x3$v5nFyd9sCKpY8_#V8UqpWsF;}X$Bh&#**n0zDOgYhQc7Q^ zL52~GcPEGc-3Sc;y%d+R#sB+5+|iMdAEA_NxZDM8e6OKpg^()Fe?w7G40Pt8EPo6} zdkidTZHxlcjZ7K8c7OV%sXa9sCdj8wjD#F2L#K}c(Z!BHW<@p$)o8MO4q2EH+go6$ zA@h}zlG5m$r{5*cb3UT({P+HMQdKy`8@nB>A(JnVD`_XU|C&Y*3_RRg4g% z1!R7m9Cdn^8SX+D4&7)D`eBt)3DH=C0G>9erPG3BWgN7`yavW_L9qc?Q^U5%Q?z`y zfzUfUqVVYoR*K~UN2dI4iLLHiP32xwAHLXkW}}ji4^{)R9OJ2{{U>iQyZV&CwQ^Du zx|u2Ec~d4K#V86Xx4q!PSQR)yr>aAu(CFIVKZ>%Ky>+@J^zHUn$6K>Z9a^6e(ijt3 zb?}-F(El*2tW|K@gXygo%q}-SY2z0*oUKMnCt^y641otpVg#Or+gFIbd#Zn>z7`TZ zx1!KM3Xxe~P7Mb3WJ_NmSlI9PvS)Je_F_R=RCJ6LQVW~zuVH1vYM&AwnK=jw4ithB zD(na9jA0nk!E;eq`G)P4r$1eRcjDgpmKJODY-Py|inE5_k_im3Hm>ZGVZ!c-Isbs= z?6YrWz?`aG!{GR5p^U0?l^$P;#(kaw8ns2lHRwRksDZ8&w1@)IGIem5i)4I+&1d7K z*9R0~wPEP)+jY#)(wGt{oGuL`d9|~N9cNJb0^%PL`wQVxpP~htns?uM!k?Gw$HdTm zAYnqy?+KOni)7)Tl<-{-S3JxmKDeHw1!~kygyVY-FkPRo#%T)NCWxMN_NIM(Sc8)?c5VEUcQ05ur=H5P5Ywy zog5eikxyENKcjIx!Q3XBYneS{?*Whytbsc=%gp^FZ2XmIH4az^ze5gpGaZArp^OPO z%o}!SbUd=uAUc`<6R3fd%xBU`V-1f%Lx$c}QKS&4y_u6(CG48?{5evE+@A!(l5t;^ zZDzvW?w6GXD2sAjyJi|9;c@>z^HZXRlhyF8zCV-b__zWlL$#+}(Qy8SCGYCyQ>!rr zhC4g7NzR6VxyT>pTSyvLD5|(TzQLx>x7!M>HB=!XA)pJXn8}L=eR4drU!rh8ME1*O zNMYB|9!hv-`5S)$xi>iJjOOAmKSqP&y{zGjGh(L61RNo|$g7o=j#2Pb2;?Ws*;rsHN`Tz@(FO>Fw@ zp#b0BU$KVMgg2L*297_{Vh-DRxcf5rvt-YdY^eLla4=DpPv?zQxt5nr_^*t+jV-fd zi|%V^ng@0vw{8sNtvdenX~Mwp6k;9$XfviTE?m#@E!-VrIM(<@RA zt6Zx{4(iscRW#y%8J2ivHH^j`#E6LRo3J(%pI-5O)-hES{&sal zPImj5uRlwahOTJO53?8ICr5w$&?$`}#lJr%|8!kY$bRHkbhDwBoc>k0{M_1cnA#cBUN`}bAzz;zB- z*%6{TX9fMvrhf?cM#1Wof$J>-()N1n(}5piHqChhx~Iy4swEE$SDi9z<@K}rtb*_NVp_&q$ zC$I5rshYh;W}``!MDGF((bSv&m8Koe_F`JQW}8+9-CZniAh=zFg`#YHPLWaq`7fAz z>1d=F6?>9|q+lWl^-zRJ+l4G(eKrRd4m>_}k>w;VTllYc%v=sIY6IX9i|s%KJ^d%y zm-a0vhZ}6+Ml_6P=R}_cnvAWZSaq?>$is1TJPa{ zLlS~MbU%={9N_uq|chwgeC35w(9=+kG z5`&vh&ugFh1oib6;IZ{-y=jjjP*go~u3k=#u53>u#M%NrXV~YJipJ7Y($w?vsNYUz za!GZ@rZQB&Z`)N>pho)(Xn&fRG$?q`R`h!v7G;<%mhff+{aL;GI>=b;s4s%?rQ z?)n!_D&p~k%@jqur16AK>`H=dp9j*sHQTTq&ZMEQgJa?=EvlEGB+!KI>juxfGPtu& z=f5VJJG`jtB|tKQ^=x>i5H}PdYu|b3wixjH>+#M6vYfQ-VqJ1?LVD~9hPgS%T(x;ZR-8M?#?@&>i_@y35kZRr0ncjgvcI= zBYR|LmQgrD$IPaXV;o7TjN%|Gt3pB@tFp6`V`Lr4$o@UwzMs!^UH@FS-|hF$^~dE8 zH-ES}-tYJ8{Th$w<8gn+mE8z3;_RB{XJt!x?*4Mm=Bs^P-LJd%*JaqM{GMwSvCjU1 z+51L^QSVBCoX(C-YdC-YJ@M%6gjTM4R7<^?U`T&b2-W2J`Hgj>V6)^9zvPg#$#sj5 zS*&QAQ9VUn#b<%R8;=cFw05N(ql|Z7PjWrp9wCf9+>S>nr_|?zQd*!*0E44Zc{V+} zlh6I_W36LZ+gG(oRvTOH06^IcNcBImTqWH0V6sAGH*=C?VOm9)i;#bwe9*|ys|FhK z2<5b@$(bKJyC=Qu&ozW{+{m*U(oPY0VPi>@%7T!%Yg=rf=*Hl(9A`1v@=oiz_@2V@ z7{Ah4>W*bOzM?Ink0@p`j>7U}8SuRrxR(P&;hWrtTPDQAFh`4Bp;W8EB<{2rnxqqK z2x@1*L3e+wj8{1`tZn{5yD#|9tRvAd5>E1fpkrF!W|*gg!?x&P+x6SrvF)Q*JjdSp z6!@Rwk*O=2w_4lQN=)0iCeeL1)aGCqMKn>Lb6o9U1DGCr+mq(EP?#$h6V+5JSm{r} zut-%4t7Jtdb4LfV%ko^$kq-OB^`JU%srV@xa`P~?153j#FDUH<+5V0o-!b@RG+IUF zKi2nb0tN+x%7oDudVaQvzBiY3{ko@V79;Csz0<=m>Kb<+?FQ7&#x*WoSUaUD;&Gfq zW{8Rit6#xAk7N+Bl+z`oT98Zqz-7Ubg-dt+UCn)6cIj0^=}{c`SBnTXgV+y4XsUGV7zv-rgc{19OG{MJg>O zHi^e0Kbfj++4FvHehc;-XYxoQvr$bbmVdb{N9TUf3G6DN{Vw_(PJ2?KjW+OI!Z+`aoEhR5KCf~2m z)!fpX*OePy3>h+UbaRxy<6q}wz>XwEs~av|U3=RGwg4wyO<0$FHF0AEoyQ{Hsk}GK z{2s)Jh-0*B7`2iIemhpu5*7&q!JQ#g#P{@x;Rb$t#Rr#Jjy~!;TvM)nYVBTCh!^8) z6WYl^KlLlqu7vSSInIoaE1Q)|Qcu?l73tNSq}Tf_dPJrYL?%T=V(h@<3W}(KqDiruUmm5<%<_ zaJO1RMoK~gz3&#A=Im5 zbJigrA2v7i*lh-1PBHL6478TXlih|rx^kR^V258GI>e*!|JYsORTpgKRxzhhyh751 zb{DYNn-Bltx;rHnr}uj;_QrI!A)V2=jwGf?&0GDFuj`K!7M-?UgrL1dWyOkB7bLV$ zZ6P4H7kk+sy}$7&%%^!%!2H7qqt2y0Rvq|n(#{2IGD~GVZ9aP<)oi!A-G5kVVyQlG zQEN;X%&G%1E8@6TlA)wC1g2xa80^7?1~W6!Gshy&cs11~v5QX=f0zL~`CUzU?WjP^ zyiE<=x3WvB{0Wz{Lq+KrIaR(NGZ$V{`8wCak?gCSc}nVJvo~RPqL9#?cjq09iRsgq=j00!|rx0cg zjNaZk{mp!?h_|sTlVO%!pR}Sfx6_JA= z7Vx^@m>$0H>8wMc7qnZJRjPTI6x3{peG8FQyx$%YG_s6+at8jhW0+P9^qYfZ(+M&% zGJMHCvd%JApd0{LuXch@$}et5UN(7;ZB`I(6@RF`6;$Z^M5XF>y%-`em0AR~$YO!U*Z>(d5X_pvLAzoZBam$+!)f~=kATB7 zmuaTg&A7$$cKFf07+b83`TOe@T%R>R;|g}NkM~5`A9s9}B?+WTv?4g~8Gig2E~2?G{ie< zCrPk%S)8F|$`$n;wup6A8C?=IKQ{SxO?{_R?VG13vvHyALB%ru0ntk|YY&=c-YE8I zBUk2~xb*@Y>iDo%PxLuA6Ufr7!bDh-?ms|6D)IBv?djqB-b4D%;%W=!OwSS}n%RTq zx9f8CF^k9NI&8)U;!DiZ1($5nQYP7q=8B$R3m>9~9~exXX) z+jxy8Q+wQqTl?cZ9Wjke9MWMyL9`=PIL+cRBNJ1zxl@*HiM4WFM9hR+r^_n$ot>=` zA7{_WYRrM!{&tPOQO8c9W#jR^eHU-De)?c7-08HcddH%kCg>qY`9S7G4{|jQNtKU4 zmo_SIwzIRt-$vQnX9Ww>@j@LWZ56=r5T~MTXlMYbQ+zsRMzazGg!%m^z=~j4MidZC zn`$JD9VBV@T^Yi3xuE}AW&V=|Yy%RHSeuCCjnr7MbnMsj7zXMA|C6uK3|u%Bh&UiV zV4z~mRlyB|p_$9Mm6S_eH*bX7X)P1i6uLxT0~A20u)@o=$I4Xn$5{v0tgUK7HL_^e{WtJ)C)lG&W5_; z((0-Pn45YO9Y&2#m?NVglovtzXu8Xo@&1!j5+ z!b!F5>T7ZT+)V**N9k+MkxstXoMW9T??QtT;3P?`GcpX&!8kdSIN1kbAXNydAtVWt z88?V`0H{JB%?LZPFCs7fE{0yoDY|7zA`%kxpy-)y#TG!k9t;NK@SHXk0LB1=ap2K~ zjWj1yLn6wbrFFh+#R}R5#R~PPIJz|pSE@aHI@Em>C2vI{JgySUR1C-sxfCOi3y_oj znwh2-bXYYJO#-iX-hzoC_HoQS2i)nWSev#C>05^7ZOBdt6v^|~KO6x578QaBBxyJ* zNU3f;A6YhWiQ;8{?Gsn;bA0dXJDRL)hZPShx)%46o-;1cCJ9X>yl{?%&aM$K6QPyP zW642vE^}x}70n$hn>YWGsqk)d4D@FFpW$-#zH|TalyU8Q%8r}6+U6Ofb~03mj~z35 z;6&BiIEToF(F3p!H9{`yT0}B|8d)Vyq^sc4i7CvJP<24sk5yy-@R3WJH+>oTe8N~k z{y!GAL;t!E!wFJNO-(=Gbb>!-1aeDH<18e8@X`H&*RB!+;T>W94u|nl&>$*UFP%Gg z0(KW_uoEo3``dmSIE?RaCUe<4Oe9L_v8^b*5$^ztqf`QT;Xf8%Gh&tXRoQbsA^Qrc za%H6(+R5?oP$()YBH<08mx3mFNY6KJO+Tpr-NLnl9wOh%m zT|e^FlqkWK9iUSk#LjzWU442qdDY_}b|R69)^BmR0W3wG#kNXN%rv0<354$JAjV$2 zyTo}({X{1%@)_S@2h`JzcG2vFN?*+=P%X|StHe0 zlB|iRJZL^QboggGH!8-&j=PZ!D5dYD4vZu70o27^3k;xeU=noPT)_u0$-M=SVrJ@L ze00i`X`18hip|R}cSt~iYj-Gl4g6$w@K9X`q`}f#DSJfvqp;s$i!YX0G%~qNg-EDj zouojpeaSQ{!$I)W@fBQ^f<~R_*~bu-6$Ll}D`4C{?AII_=yGXcH@cG~AD{M<7pXjf zTK*#Q6EpPdU2w_-u^2{WG)$9o>wIQji`(@AEA>kH)fNG7Y~EXSTzJU@5sFc++Jv?W zmOS<_5$n=$+9rY+fiwB(n%8=%#W^Lav*3sXnIBDlRz?D?c2-6j9bWD=ak+v~4B+`8 zjIzm99!ftxypVh(dxP!MRf~j}SQO@Bd+AXl=fY1@x1v4w8jKXba~CAtrh)0O5e~rT z0i@FN+WHKrg8EQLd#S%hzXuI%AqW|{dlTVW^u@R^GkJ z$!&@J(SoGbfwET^5cgnHMg?o-OXnkwv6b!8w5Kl|MrzH_0HSA$9ulxH=;HnVLVdz; z^_=k_wf4?^7$f;qIZ*aA4Tzfb$yA7r-JhVb9W6<^`3a)s9e^%Zfnr*3dsw?P%JcTO z=b;w!L2mH3X>;DD>KP;12zx6YG0w`mkkvsd_~gAX`E}9Rh^!C z!aW!R^QOzA&I2KQC=yIyQ4mGX`!NqaWoaTH469B#4UPZCcLGi_0V!z^wjT(l5YQm_ zek;sEYX5bNC@wmES>K5LcB`6hrP(h02a+xTmTzf15~ydG|lrLLkZ`?9xK1!6cfJydbRVHC;2u3 zlRhSjQ4o5B7ZKZ?m?7mN&Rd&4$)|gJ3IWopmZzmL??-wSq5K#QeV!e_H*hgz_q`Bn zBMU7z+P92n6KbT;Q}msGwLoMU4@H`Q!9gejx}s1}EBgka%GJ{~(D(tOiqBLY#aJOZ z#+nEO5ag_lbAto4dPQc^Np7GJM?j6wLI_5N`5X5E!wyB%fHtA_z=2~%TIwpsWGpqZ z+W?}b1Jr`j5rDrW^~?U^c+xlbgprU`+W;;OH3&-e%ngITzL&fib}>sn2{Bh-|H&_ca^hE%==)K<~hc+bWuPSz2I$q>?u|)RjO4%sBobKOHtV*XodH zP&hQDje$L0!Ds`VV#Z8c3DOMaf|3rOj=GP$H7QELwsu(wssYXhUNiN2E}2|tl552D z1~%>wLEJA0vqN^6FzNMPbWvn3|`#5&tc-v_oo0&T!0DTzfE!d0U0L3^(_y~?S`gO^BhJwda3UW8LRacXvMIExG3+=88KD!m z2HzN<&O$`&^_udHHrz3d`-}z}XveYV?W`^C6>mxhYXfB9#=UZmh3N9?4G<`jScae* zzz_H+d~+vE1IAv$E|ERZi?*Uwz0!rSYn#4v?C4QrOR1c`Pzncg?pnaZZG+Fl>JX$V z`C&bZnQww=8hrK&6)Bc$sv!TLLTD!d68rWZwfrT#<-1tiqDe)cBQY)D@Jh`J#yAdmzt1Be!V0 z9%p1REQ&co(@1%xw%)xQL6mLE8&2G7NP`e3yf1XJr>JWsy6-?r8QH3RFR=?35L^&V_Dg=?2u>AhV1Rv|&YV*+hMwrj5_r}i>KX4YWn zwBsk!N;RFw7qlwmk|x{Xrkhnz0jm5}Sd$V5UU0Y`Ep z6woC6uy#kNhS8@rof)(uLn}U}eZ*ufTE8)uWC6NLym~XRj zTy1Jxg4cQL+hCqFC=hXM3p4gc;KVc)64}CS=}s=?85tQg?+x{f0pRIs8D2;L-vdAdvn~2v%q8N_A@PC_UaO$^sXF3Vn|70P64(5BN}5ctzUSQP2zg z51*X{ey&x~HN65i;N~J@1W+ZD5zCL&?KW+Op6L}CN+ETF#e$NUvZE#z?pkEoz@aIl zFJ{o%*y2%WHri7}0AeL${4N1J^?GF@7Hbr3q-5iWDH4EKohV=?qGQo^-gd01Z2#NR z?z0^Cj8Pz&MaktVR3n}0UmBBAS(FC41to(Go6VfJb9`{^o6vZ}tYce?OEP^YIq16t zxj-8sL&_}*Sb5n9`UuG&Sc`^g;Sy0^lE27=8?9Q#-o?y?BjQLV>$MmC%j!v9~jYwpUW9)A@M)XKH2>#_m#XHq+LaZG*QTBe+adyge zEfX0?i{_GOlmiUNDybLTwNfZyRKn!g)wSW)`lpOflR}gPFY}^Oc)z#SXGaWyd2@UE zK85+<6Mv1c?IBN%gTSr=%M5&HqE@^JZz!2gr5vixH!}jPT@O! zol|}xg(tNy{YOnGZH7H<*M&>zvout=cJQ$=GcLUqh|+mK_)zUm#g&Xo$;$j(3YeN2 z5rwpSX24(WebC2Fi@C>1OP_Py7!Gm0W5htzi+*Ej|UI%69PcWQCAn^-(7Yz{xTKMhb67BptPFWirDB9 zB`L~pKl*rgUPCAE37dxhLSw)VaA82QM(z(`vgs*XuvT7 zu|54kGCCsZ!H0A!QFj#I|7F?#LFSJeQ|dGPhao0zCe-wpYxd=ZLx<<2sLzPkHm_@R z{;n={J}2js5uHrBeSPS!?%^U+GA4XfR(Hg$YL=q04xYs({gkESp9qqIYiyrc8}4zB z3dk(}tSZ)me`XDgSHM}(`zh(Zz)Df<9-7yUITuCyE3%TS;bzq=lUNbk13PQ{+2RbU z`!Z}1d{aTN96eA`*8zz&IJ6xc+S1~%;qDxhd4eBc^I{kyzY3OlULBT zpP^1azZ@4nS z&_=i66a+y()|%%{PR4dQe0}A=r!N24jLPQak4xJr6t--MwW{aV#~=3QO^C;9V)XQS z9(fHhej?dBU-kIAKKzV3hd*|J?zk=K(6#L+y#S+)nWsi(2-z3v@*|f{`;dc5+d&mt z@y>pBap=k@`x8^;1chPR(8Ymo=#d*iQ|}&)SY!J~n8$~BXJ>i)WQXig_jf*V|Nf=g z^JiK4*ZJua&pgSEgaQi8=Q&KTWi-wIO4uG%q5={YcbVw^khkfi^>UxQ_C{=)%5Po% z=9`(9gKqFCrj!-(@4tEeLe=*FefKqEkn>f*0e`l{yaICcTHp5+AD;ku?`(rs#;7x*0jml} z>xbehYevS0L=0=c`aLVDH{+BKw6yOK#)RA0iw4AJ8}bqFT0ONg7j4!Z3}=mB7!O{0 zeTm~?@ZUh{YN?{r?~klC?e-Y8As=Rh>;#E-=>Kn716oHipP$*7yot$#dzEgUTO)4r z{+kVqDcN3fS@eO!-r1kN9lPiux4zLK%KDfg%6?Qa@7!9BO;!hpHa>{GnEz`95-Yr3js7 zW53YN$}m-N`8RRhr!DHkWd_fg=JlQoPj5L_N8x+Am&WEKUyASelUq!;By1kx*nN`% z?86v$sHDKFYc%gRT<3Z4bHdZ6R85Ya(FqQXiQkg~tg&z7G@pgU;i);;e;W1}uqxR3 z554N)NM}uKEIB`zl0P>5sfK~y>-X-vXLu)+(v+0wpN}$k&a=;$PyXA=vDR6h4+fG9 za^KZimK~ILpH>%i>r0w(zMT(@{QK(6x3|}CU$}NxIR1k!{6^*e)+2?BnVj02# z&+WGIW1gIdy1XMjJAk~_|Ng0@PGpKzPY6S<0Qn+B{QvRO;SYPX3*6)K&nU?S4#1a| MhOYW+)$3vZ1rQTAG5`Po literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/reference/apis/js-apis-media.md b/zh-cn/application-dev/reference/apis/js-apis-media.md index 22bbb399832..718a612763e 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-media.md +++ b/zh-cn/application-dev/reference/apis/js-apis-media.md @@ -1,34 +1,95 @@ -# 音频播放和录制 +# 媒体服务 + +媒体子系统为开发者提供一套简单且易于理解的接口,使得开发者能够方便接入系统并使用系统的媒体资源。 + +媒体子系统包含了音视频相关媒体业务,提供以下常用功能: + +- 音频播放([AudioPlayer](#audioplayer)) +- 音频录制([AudioRecorder](#audiorecorder)) + +后续将提供以下功能:视频播放、视频录制、DataSource音视频播放、音视频编解码、容器封装解封装、媒体能力查询等功能。 ## 导入模块 -``` +```js import media from '@ohos.multimedia.media'; ``` +## media.createAudioPlayer -## 权限 +createAudioPlayer(): [AudioPlayer](#audioplayer) -无 +同步方式创建音频播放实例。 +**返回值:** -## media.createAudioPlayer +| 类型 | 说明 | +| --------------------------- | ------------------------------------------------------------ | +| [AudioPlayer](#audioplayer) | 返回AudioPlayer类实例,失败时返回null。可用于音频播放、暂停、停止等操作。 | -createAudioPlayer(): AudioPlayer +**示例:** -创建音频播放的实例。 +```js +var audioPlayer = media.createAudioPlayer(); +``` -**返回值:** +## media.createAudioPlayerAsync8+ + +createAudioPlayerAsync(callback: AsyncCallback\<[AudioPlayer](#audioplayer)>): void -| 类型 | 说明 | -| -------- | -------- | -| [AudioPlayer](#audioplayer) | 返回AudioPlayer类实例,失败时返回null。 | +异步方式创建音频播放实例。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------ | ---- | ------------------------------ | +| callback | AsyncCallback<[AudioPlayer](#audioplayer)> | 是 | 异步创建音频播放实例回调方法。 | **示例:** +```js +media.createAudioPlayerAsync((error, audio) => { + if (typeof(audio) != 'undefined') { + audioPlayer = audio; + console.info('audio createAudioPlayerAsync success'); + } else { + console.info(`audio createAudioPlayerAsync fail, error:${error.message}`); + } +}); ``` -var audioplayer = media.createAudioPlayer(); + +## media.createAudioPlayerAsync8+ + +createAudioPlayerAsync: Promise<[AudioPlayer](#audioplayer)> + +异步方式创建音频播放实例。通过Promise获取返回值。 + +**返回值:** + +| 类型 | 说明 | +| ------------------------------------ | ----------------------------------- | +| Promise<[AudioPlayer](#audioplayer)> | 异步创建音频播放实例Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`audio failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`audio catchCallback, error:${error.message}`); +} + +await media.createAudioPlayerAsync.then((audio) => { + if (typeof(audio) != 'undefined') { + audioPlayer = audio; + console.info('audio createAudioPlayerAsync success'); + } else { + console.info('audio createAudioPlayerAsync fail'); + } +}, failureCallback).catch(catchCallback); ``` + ## media.createAudioRecorder createAudioRecorder(): AudioRecorder @@ -41,42 +102,109 @@ createAudioRecorder(): AudioRecorder | [AudioRecorder](#audiorecorder) | 返回AudioRecorder类实例,失败时返回null。 | **示例:** + ``` var audiorecorder = media.createAudioRecorder(); ``` +## MediaErrorCode8+ + +媒体服务错误类型枚举 + +| 名称 | 值 | 说明 | +| -------------------------- | ---- | -------------------------------------- | +| MSERR_OK | 0 | 表示操作成功。 | +| MSERR_NO_MEMORY | 1 | 表示申请内存失败,系统可能无可用内存。 | +| MSERR_OPERATION_NOT_PERMIT | 2 | 表示无权限执行此操作。 | +| MSERR_INVALID_VAL | 3 | 表示传入入参无效。 | +| MSERR_IO | 4 | 表示发生IO错误。 | +| MSERR_TIMEOUT | 5 | 表示操作超时。 | +| MSERR_UNKNOWN | 6 | 表示未知错误。 | +| MSERR_SERVICE_DIED | 7 | 表示服务端失效。 | +| MSERR_INVALID_STATE | 8 | 表示在当前状态下,不允许执行此操作。 | +| MSERR_UNSUPPORTED | 9 | 表示在当前版本下,不支持此操作。 | + +## MediaType8+ + +媒体类型枚举 + +| 名称 | 值 | 说明 | +| ------------------- | ---- | ------------------ | +| MEDIA_TYPE_AUD | 0 | 表示音频。 | +| MEDIA_TYPE_VID | 1 | 表示视频。 | +| MEDIA_TYPE_SUBTITLE | 2 | 表示字幕:开发中。 | + +## CodecMimeType8+ + +Codec MIME类型枚举 + +| 名称 | 值 | 说明 | +| ------------ | ----------------- | ------------------------ | +| AUDIO_MPEG | "audio/mpeg" | 表示音频/mpeg类型。 | +| AUDIO_AAC | "audio/mp4a-latm" | 表示音频/mp4a-latm类型。 | +| AUDIO_VORBIS | "audio/vorbis" | 表示音频/vorbis类型。 | +| AUDIO_FLAC | "audio/flac" | 表示音频/flac类型。 | + +## MediaDescriptionKey8+ + +媒体信息描述枚举 + +| 名称 | 值 | 说明 | +| ------------------------ | --------------- | ------------------------------------------------------------ | +| MD_KEY_TRACK_INDEX | "track_index" | 表示轨道序号,其对应键值类型为number。 | +| MD_KEY_TRACK_TYPE | "track_type" | 表示轨道类型,其对应键值类型为number,参考[MediaType](#mediatype8)。 | +| MD_KEY_CODEC_MIME | "codec_mime" | 表示codec_mime类型,其对应键值类型为string。 | +| MD_KEY_DURATION | "duration" | 表示媒体时长,其对应键值类型为number,单位为ms。 | +| MD_KEY_BITRATE | "bitrate" | 表示比特率,其对应键值类型为number,单位为bps。 | +| MD_KEY_WIDTH | "width" | 表示视频宽度,其对应键值类型为number,单位为像素。 | +| MD_KEY_HEIGHT | "height" | 表示视频高度,其对应键值类型为number,单位为像素。 | +| MD_KEY_FRAME_RATE | "frame_rate" | 表示视频帧率,其对应键值类型为number,单位为100fps。 | +| MD_KEY_AUD_CHANNEL_COUNT | "channel_count" | 表示声道数,其对应键值类型为number。 | +| MD_KEY_AUD_SAMPLE_RATE | "sample_rate" | 表示采样率,其对应键值类型为number,单位为HZ。 | + +## BufferingInfoType8+ + +缓存事件类型枚举 + +| 名称 | 值 | 说明 | +| ----------------- | ---- | -------------------------- | +| BUFFERING_START | 1 | 表示开始缓存。 | +| BUFFERING_END | 2 | 表示结束缓存。 | +| BUFFERING_PERCENT | 3 | 表示缓存百分比。 | +| CACHED_DURATION | 4 | 表示缓存时长,单位为毫秒。 | + ## AudioPlayer -音频播放管理类,用于管理和播放音频媒体。在调用AudioPlayer的方法前,需要先通过[createAudioPlayer()](#createaudioplayer-)构建一个AudioPlayer实例。 +音频播放管理类,用于管理和播放音频媒体。在调用AudioPlayer的方法前,需要先通过[createAudioPlayer()](#media.createaudioplayer)或[createAudioPlayerAsync()](#media.createaudioplayerasync8)构建一个[AudioPlayer](#audioplayer)实例。 +音频播放demo可参考:[音频播放开发指导](../../media/audio-playback.md) -### 属性 +### 属性 -| 名称 | 参数类型 | 可读 | 可写 | 说明 | -| -------- | -------- | -------- | -------- | -------- | -| src | string | 是 | 是 | 音频媒体URI,支持当前主流的音频格式(mp4、aac、mp3、ogg),支持本地绝对路径(file://) | -| loop | boolean | 是 | 是 | 音频循环播放属性,设置为'true'表示循环播放。 | -| currentTime | number | 是 | 否 | 音频的当前播放阶段。 | -| duration | number | 是 | 否 | 音频时长。 | -| state | [AudioState](#audiostate) | 是 | 否 | 音频播放的状态。 | +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ----------- | ------------------------- | ---- | ---- | ------------------------------------------------------------ | +| src | string | 是 | 是 | 音频媒体URI,支持当前主流的音频格式(mp4、aac、mp3、ogg)。
**支持路径示例**:
1、本地绝对路径:file:///data/data/ohos.xxx.xxx/files/test.mp4
![zh-cn_image_0000001164217678](figures/zh-cn_image_0000001164217678.png)
2、http网络播放路径:开发中
3、hls网络播放路径:开发中
4、fd类型播放:开发中
**注意事项**:
媒体素材需至少赋予读权限后,才可正常播放 | +| loop | boolean | 是 | 是 | 音频循环播放属性,设置为'true'表示循环播放。 | +| currentTime | number | 是 | 否 | 音频的当前播放位置。 | +| duration | number | 是 | 否 | 音频时长。 | +| state | [AudioState](#audiostate) | 是 | 否 | 音频播放的状态。 | -### play +### play play(): void -开始播放音频资源。 +开始播放音频资源,需在[dataLoad](#on('play' | 'pause' | 'stop' | 'reset' | 'dataload' | 'finish' | 'volumechange'))事件成功触发后,才能调用play方法。 **示例:** -``` -audioplayer.src = 'file:///data/media/sounds.mp4'; -audioplayer.on('play', () => { - console.log('Playback starts.'); +```js +audioPlayer.on('play', () => { //设置'play'事件回调 + console.log('audio play success'); }); -audioplayer.play(); +audioPlayer.play(); ``` -### pause +### pause pause(): void @@ -84,15 +212,14 @@ pause(): void **示例:** -``` -audioplayer.src = 'file:///data/media/sounds.mp4'; -audioplayer.on('pause', () => { - console.log('Playback paused.'); +```js +audioPlayer.on('pause', () => { //设置'pause'事件回调 + console.log('audio pause success'); }); -audioplayer.pause(); +audioPlayer.pause(); ``` -### stop +### stop stop(): void @@ -100,15 +227,29 @@ stop(): void **示例:** +```js +audioPlayer.on('stop', () => { //设置'stop'事件回调 + console.log('audio stop success'); +}); +audioPlayer.stop(); ``` -audioplayer.src = 'file:///data/media/sounds.mp4'; -audioplayer.on('stop',() => { - console.log('Playback stopped.'); + +### reset7+ + +reset(): void + +切换播放音频资源。 + +**示例:** + +```js +audioPlayer.on('reset', () => { //设置'reset'事件回调 + console.log('audio reset success'); }); -audioplayer.stop(); +audioPlayer.reset(); ``` -### seek +### seek seek(timeMs: number): void @@ -116,26 +257,24 @@ seek(timeMs: number): void **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------- | -------- | -------- | -| timeMs | number | 是 | 指定的跳转时间节点。 | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ------------------------------ | +| timeMs | number | 是 | 指定的跳转时间节点,单位毫秒。 | **示例:** -``` -audioplayer.src = 'file:///data/media/sounds.mp4'; -audioplayer.on('timeupdate', (action) => { - var newTime = audioplayer.currenTime; - if(newTime >= 30000) { - console.info('Seek succeeded. New time: ' + newTime); - } else { - console.info('Seek failed.'); - } +```js +audioPlayer.on('timeUpdate', (seekDoneTime) => { //设置'timeUpdate'事件回调 + if (typeof (seekDoneTime) == 'undefined') { + console.info('audio seek fail'); + return; + } + console.log('audio seek success. seekDoneTime: ' + seekDoneTime); }); -audioplayer.seek(30000); +audioPlayer.seek(30000); //seek到30000ms的位置 ``` -### setVolume +### setVolume setVolume(vol: number): void @@ -143,128 +282,279 @@ setVolume(vol: number): void **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------- | -------- | -------- | -| vol | number | 是 | 指定的相对音量大小,取值范围为[0.00-1.00],1表示最大音量,即100%。 | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ------------------------------------------------------------ | +| vol | number | 是 | 指定的相对音量大小,取值范围为[0.00-1.00],1表示最大音量,即100%。 | **示例:** -``` -audioplayer.src = 'file:///data/media/sounds.mp4'; -audioplayer.on('volumeChange', () => { - console.log('Playback volume changed.'); +```js +audioPlayer.on('volumeChange', () => { //设置'volumeChange'事件回调 + console.log('audio volumeChange success'); }); -audioplayer.setVolume(1); +audioPlayer.setVolume(1); //设置音量到100% ``` -### reset7+ +### release -reset(): void +release(): void -切换播放音频资源。 +释放音频资源。 **示例:** -``` -audioplay.reset(); +```js +audioPlayer.release(); +audioPlayer = undefined; ``` -### release7+ +### getTrackDescription8+ -release(): void +getTrackDescription(callback: AsyncCallback>): void -释放音频资源。 +通过回调方式获取音频轨道信息。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------------------------ | ---- | -------------------------- | +| callback | AsyncCallback> | 是 | 获取音频轨道信息回调方法。 | **示例:** +```js +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('audio key is ' + item); + console.info('audio value is ' + property); + } +} + +audioPlayer.getTrackDescription((error, arrlist) => { + if (typeof (arrlist) != 'undefined') { + for (let i = 0; i < arrlist.length; i++) { + printfDescription(arrlist[i]); + } + } else { + console.log(`audio getTrackDescription fail, error:${error.message}`); + } +}); ``` -audioplay.release(); + +### getTrackDescription8+ + +getTrackDescription(): Promise> + +通过Promise方式获取音频轨道信息。 + +**返回值:** + +| 类型 | 说明 | +| ------------------------------------------------------ | ------------------------------- | +| Promise> | 获取音频轨道信息Promise返回值。 | + +**示例:** + +```js +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('audio key is ' + item); + console.info('audio value is ' + property); + } +} +function failureCallback(error) { + console.info(`audio failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`audio catchCallback, error:${error.message}`); +} + +await audioPlayer.getTrackDescription.then((arrlist) => { + if (typeof (arrlist) != 'undefined') { + arrayDescription = arrlist; + } else { + console.log('audio getTrackDescription fail'); + } +}, failureCallback).catch(catchCallback); +for (let i = 0; i < arrayDescription.length; i++) { + printfDescription(arrayDescription[i]); +} ``` -### on('play' | 'pause' | 'stop' | 'reset' | 'dataLoad' | 'finish' | 'volumeChange') +### on('bufferingUpdate')8+ -on(type: 'play' | 'pause' | 'stop' | 'reset' | 'dataLoad' | 'finish' | 'volumeChange', callback: () => void) +on(type: 'bufferingUpdate', callback: (infoType: [BufferingInfoType](#bufferinginfotype8), value: number) => void): void -开始监听音频播放事件。 +开始订阅音频缓存更新事件。 **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------- | -------- | -------- | -| type | string | 是 | 播放事件回调类型,支持的事件包括:'play' \| 'pause' \| 'stop' \| 'reset' \| 'dataLoad' \| 'finish' \| 'volumeChange'。
- 'play' :完成play方法调用,音频开始播放,触发该事件。
- 'pause':完成pause方法调用,音频暂停播放,触发该事件。
- 'stop':完成stop方法调用,音频停止播放,触发该事件。
- 'reset':完成reset方法调用,播放器重置,触发该事件。
- 'dataLoad':完成音频数据加载后触发该事件。
- 'finish':完成音频播放后触发该事件。
- 'volumeChange':播放音量改变后触发该事件。播放事件回调方法。 | -| callback | function | 是 | 播放事件回调方法。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | +| type | string | 是 | 音频缓存事件回调类型,支持的事件:'bufferingUpdate'。 | +| callback | (infoType: [BufferingInfoType](#bufferinginfotype8), value: number) => void | 是 | 音频缓存事件回调方法。
[BufferingInfoType](#bufferinginfotype8)为BUFFERING_PERCENT或CACHED_DURATION时,value值有效,否则固定为0。 | **示例:** +```js +audioPlayer.on('bufferingUpdate', (infoType, value) => { + console.log('audio bufferingInfo type: ' + infoType); + console.log('audio bufferingInfo value: ' + value); +}); ``` -audioplayer.src = 'file://xxx/sounds.mp4'; -audioplayer.on('play', () => { - console.log('Playback starts.'); + + ### on('play' | 'pause' | 'stop' | 'reset' | 'dataLoad' | 'finish' | 'volumeChange') + +on(type: 'play' | 'pause' | 'stop' | 'reset' | 'dataLoad' | 'finish' | 'volumeChange', callback: () => void): void + +开始订阅音频播放事件。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 播放事件回调类型,支持的事件包括:'play' \| 'pause' \| 'stop' \| 'reset' \| 'dataLoad' \| 'finish' \| 'volumeChange'。
- 'play':完成[play()](#audioplayer_play)调用,音频开始播放,触发该事件。
- 'pause':完成[pause()](#audioplayer_pause)调用,音频暂停播放,触发该事件。
- 'stop':完成[stop()](#audioplayer_stop)调用,音频停止播放,触发该事件。
- 'reset':完成[reset()](#audioplayer_reset)调用,播放器重置,触发该事件。
- 'dataLoad':完成音频数据加载后触发该事件,即src属性设置完成后触发该事件。
- 'finish':完成音频播放后触发该事件。
- 'volumeChange':完成[setVolume()](#audioplayer_setvolume)调用,播放音量改变后触发该事件。 | +| callback | () => void | 是 | 播放事件回调方法。 | + +**示例:** + +```js +let audioPlayer = media.createAudioPlayer(); //创建一个音频播放实例 +audioPlayer.on('dataLoad', () => { //设置'dataLoad'事件回调,src属性设置成功后,触发此回调 + console.info('audio set source success'); + audioPlayer.play(); //开始播放,并触发'play'事件回调 +}); +audioPlayer.on('play', () => { //设置'play'事件回调 + console.info('audio play success'); + audioPlayer.seek(30000); //调用seek方法,并触发'timeUpdate'事件回调 +}); +audioPlayer.on('pause', () => { //设置'pause'事件回调 + console.info('audio pause success'); + audioPlayer.stop(); //停止播放,并触发'stop'事件回调 }); -audioplayer.play(); +audioPlayer.on('reset', () => { //设置'reset'事件回调 + console.info('audio reset success'); + audioPlayer.release(); //释放播放实例资源 + audioPlayer = undefined; +}); +audioPlayer.on('timeUpdate', (seekDoneTime) => { //设置'timeUpdate'事件回调 + if (typeof(seekDoneTime) == "undefined") { + console.info('audio seek fail'); + return; + } + console.info('audio seek success, and seek time is ' + seekDoneTime); + audioPlayer.setVolume(0.5); //设置音量为50%,并触发'volumeChange'事件回调 +}); +audioPlayer.on('volumeChange', () => { //设置'volumeChange'事件回调 + console.info('audio volumeChange success'); + audioPlayer.pause(); //暂停播放,并触发'pause'事件回调 +}); +audioPlayer.on('finish', () => { //设置'finish'事件回调 + console.info('audio play finish'); + audioPlayer.stop(); //停止播放,并触发'stop'事件回调 +}); +audioPlayer.on('error', (error) => { //设置'error'事件回调 + console.info(`audio error called, errName is ${error.name}`); + console.info(`audio error called, errCode is ${error.code}`); + console.info(`audio error called, errMessage is ${error.message}`); +}); +audioPlayer.src = 'file:///data/data/ohos.xxx.xxx/files/test.mp4'; //设置src属性,并触发'dataLoad'事件回调 ``` ### on('timeUpdate') on(type: 'timeUpdate', callback: Callback\): void -开始监听音频播放时间戳更新事件。 +开始订阅音频播放[seek()](#audioplayer_seek)时间更新事件。 **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------- | -------- | -------- | -| type | string | 是 | 播放事件回调类型,支持的事件为:'timeUpdate'。
'timeUpdate':音频播放时间戳更新,触发该事件。seek方法调用时也会触发该事件。 | -| callback | Callback<number> | 是 | 播放事件回调方法。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 播放事件回调类型,支持的事件包括:'timeUpdate'。
- 'timeUpdate':[seek()](#audioplayer_seek)调用完成,触发该事件。 | +| callback | Callback\ | 是 | 播放事件回调方法。回调方法入参为成功seek的时间。 | **示例:** -``` -audioplayer.src = 'file://xxx/sounds.mp4'; -audioplayer.on('timeupdate', (newTime ) => { - if(newTime >= 30000) { - console.info('Seek succeeded. New time: ' + newTime); - } else { - console.info('Seek failed.'); - } +```js +audioPlayer.on('timeUpdate', (seekDoneTime) => { //设置'timeUpdate'事件回调 + if (typeof (seekDoneTime) == 'undefined') { + console.info('audio seek fail'); + return; + } + console.log('audio seek success. seekDoneTime: ' + seekDoneTime); }); -audioplayer.seek(30000); +audioPlayer.seek(30000); //seek到30000ms的位置 ``` ### on('error') on(type: 'error', callback: ErrorCallback): void -开始监听音频播放错误事件。 +开始订阅音频播放错误事件。 **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------- | -------- | -------- | -| type | string | 是 | 播放错误事件回调类型'error'。
'error':音频播放中发生错误,触发该事件。 | -| callback | ErrorCallback | 是 | 播放错误事件回调方法。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 播放错误事件回调类型,支持的事件包括:'error'。
- 'error':音频播放中发生错误,触发该事件。 | +| callback | ErrorCallback | 是 | 播放错误事件回调方法。 | **示例:** -``` -audioplayer.src = 'file:///data/sounds.mp4'; -audioplayer.on('error', (err) => { - console.info('error callback info: ' + err); +```js +audioPlayer.on('error', (error) => { //设置'error'事件回调 + console.info(`audio error called, errName is ${error.name}`); //打印错误类型名称 + console.info(`audio error called, errCode is ${error.code}`); //打印错误码 + console.info(`audio error called, errMessage is ${error.message}`);//打印错误类型详细描述 }); -audioplayer.setVolume(30000); +audioPlayer.setVolume(3); //设置volume为无效值,触发'error'事件 ``` - ## AudioState -音频播放的状态机。 +音频播放的状态机。可通过state属性获取当前状态。 + +| 名称 | 类型 | 描述 | +| ------------------ | ------ | -------------- | +| idle | string | 音频播放空闲。 | +| playing | string | 音频正在播放。 | +| paused | string | 音频暂停播放。 | +| stopped | string | 音频播放停止。 | +| error8+ | string | 错误状态。 | + +## MediaDescription8+ + +### [key : string] : any + +通过key-value方式获取媒体信息 -| 名称 | 描述 | -| -------- | -------- | -| idle | 音频播放空闲。 | -| playing | 音频正在播放。 | -| paused | 音频暂停播放。 | -| stopped | 音频播放停止。 | +| 名称 | 类型 | 说明 | +| ----- | ------ | ------------------------------------------------------------ | +| key | string | 通过key值获取对应的value。key值具体可见[MediaDescriptionKey](#mediadescriptionkey8)。 | +| value | any | 对应key值得value。其类型可为任意类型,具体key对应value的类型可参考[MediaDescriptionKey](#mediadescriptionkey8)的描述信息。 | + +**示例:** + +```js +function printfItemDescription(obj, key) { + let property = obj[key]; + console.info('audio key is ' + key); + console.info('audio value is ' + property); +} + +audioPlayer.getTrackDescription((error, arrlist) => { + if (typeof (arrlist) != 'undefined') { + for (let i = 0; i < arrlist.length; i++) { + printfItemDescription(arrlist[i], MD_KEY_TRACK_TYPE); //打印出每条轨道MD_KEY_TRACK_TYPE的值 + } + } else { + console.log(`audio getTrackDescription fail, error:${error.message}`); + } +}); +``` ## AudioRecorder -- Gitee