1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import media from '@ohos.multimedia.media' 17import * as mediaTestBase from './MediaTestBase.js'; 18 19export const AV_PLAYER_STATE = { 20 IDLE : 'idle', 21 INITIALIZED : 'initialized', 22 PREPARED : 'prepared', 23 PLAYING : 'playing', 24 PAUSED : 'paused', 25 COMPLETED : 'completed', 26 STOPPED : 'stopped', 27 RELEASED : 'released', 28 ERROR : 'error', 29} 30 31let playTest = { 32 width: 0, 33 height: 0, 34 duration: -1 35} 36export {playTest}; 37 38export function setSource(avPlayer, src) { 39 if (typeof(avPlayer) == 'undefined') { 40 console.error('case avPlayer is undefined'); 41 return; 42 } 43 if (typeof(src) == 'string') { 44 console.info('case src test'); 45 avPlayer.url = src; 46 } else { 47 console.info('case fdsrc test'); 48 avPlayer.fdSrc = src; 49 } 50} 51 52function checkPlayTest(avPlayer, playTest) { 53 if (avPlayer == null) { 54 return; 55 } 56 expect(Math.abs(avPlayer.duration - playTest.duration)).assertLess(500); 57 if (playTest.width > 0) { 58 expect(avPlayer.width).assertEqual(playTest.width); 59 expect(avPlayer.height).assertEqual(playTest.height); 60 } 61} 62 63function toPreparePromise(avPlayer, playTest) { 64 if (typeof(avPlayer) == 'undefined') { 65 return; 66 } 67 avPlayer.prepare().then(() => { 68 console.info('case prepare called'); 69 console.info('case avPlayer.duration: ' + avPlayer.duration); 70 checkPlayTest(avPlayer, playTest); 71 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 72} 73 74function addCnt(countArr) { 75 if (countArr != null) { 76 countArr[0]++; 77 } 78} 79 80export function setCallback(avPlayer, type, countArr) { 81 if (avPlayer == null) { 82 return; 83 } 84 switch (type) { 85 case 'volumeChange': 86 avPlayer.on('volumeChange', (volume) => { 87 console.info(`case volumeChange called, volume is ${volume}`); 88 addCnt(countArr); 89 }); 90 break; 91 case 'endOfStream': 92 avPlayer.on('endOfStream', () => { 93 console.info(`case endOfStream called`); 94 addCnt(countArr); 95 }); 96 break; 97 case 'speedDone': 98 avPlayer.on('speedDone', (speedMode) => { 99 console.info(`case speedDone called, speedMode is ${speedMode}`); 100 addCnt(countArr); 101 }); 102 break; 103 case 'bitrateDone': 104 avPlayer.on('bitrateDone', (bitrate) => { 105 console.info(`case bitrateDone called, bitrate is ${bitrate}`); 106 }); 107 break; 108 case 'timeUpdate': 109 avPlayer.on('timeUpdate', (time) => { 110 console.info('case timeUpdate callback, time:' + time); 111 }); 112 break; 113 case 'bufferingUpdate': 114 avPlayer.on('bufferingUpdate', (infoType, value) => { 115 }); 116 break; 117 case 'durationUpdate': 118 avPlayer.on('durationUpdate', (duration) => { 119 console.info('case durationUpdate called,duration:' + duration); 120 addCnt(countArr); 121 }); 122 break; 123 case 'startRenderFrame': 124 avPlayer.on('startRenderFrame', () => { 125 console.info('case startRenderFrame called'); 126 addCnt(countArr); 127 }); 128 break; 129 case 'videoSizeChange': 130 avPlayer.on('videoSizeChange', (w, h) => { 131 console.info(`case videoSizeChange called, weight is ${w}, height is ${h}`); 132 addCnt(countArr); 133 }); 134 break; 135 case 'audioInterrupt': 136 avPlayer.on('audioInterrupt', (info) => { 137 console.info(`case audioInterrupt called, info is ${info}`); 138 }); 139 break; 140 case 'availableBitrates': 141 avPlayer.on('availableBitrates', (bitrates) => { 142 for (let i = 0; i < bitrates.length; i++) { 143 console.info('case availableBitrates : ' + bitrates[i]); 144 } 145 addCnt(countArr); 146 }); 147 break; 148 default: 149 break; 150 } 151} 152 153export function offCallback(avPlayer, typeArr) 154{ 155 if (avPlayer == null) { 156 return; 157 } 158 for (let i = 0; i < typeArr.length; i++) { 159 switch (typeArr[i]) { 160 case 'stateChange': 161 avPlayer.off('stateChange'); 162 break; 163 case 'volumeChange': 164 avPlayer.off('volumeChange'); 165 break; 166 case 'endOfStream': 167 avPlayer.off('endOfStream'); 168 break; 169 case 'seekDone': 170 avPlayer.off('seekDone'); 171 break; 172 case 'speedDone': 173 avPlayer.off('speedDone'); 174 break; 175 case 'speedDone': 176 avPlayer.off('speedDone'); 177 break; 178 case 'timeUpdate': 179 avPlayer.off('timeUpdate'); 180 break; 181 case 'durationUpdate': 182 avPlayer.off('durationUpdate'); 183 break; 184 case 'bufferingUpdate': 185 avPlayer.off('bufferingUpdate'); 186 break; 187 case 'startRenderFrame': 188 avPlayer.off('startRenderFrame'); 189 break; 190 case 'videoSizeChange': 191 avPlayer.off('videoSizeChange'); 192 break; 193 case 'audioInterrupt': 194 avPlayer.off('audioInterrupt'); 195 break; 196 case 'availableBitrates': 197 avPlayer.off('availableBitrates'); 198 break; 199 case 'error': 200 avPlayer.off('error'); 201 break; 202 default: 203 break; 204 } 205 } 206} 207 208export function setAVPlayerFunCb(src, avPlayer, playTest, playTime, done) { 209 let volumeCnt = [0]; 210 let endOfStreamCnt = [0]; 211 let speedDoneCnt = [0]; 212 let videoSizeCnt = [0]; 213 let startRenderFrameCnt = [0]; 214 let durationUpdateCnt = [0]; 215 let seekDoneCnt = [0]; 216 let prepareCnt = 0; 217 let playCnt = 0; 218 let completedCnt = 0; 219 let surfaceID = globalThis.value; 220 console.info(`case setAVPlayerFunCb in, surfaceID is ${surfaceID}`); 221 avPlayer.on('stateChange', async (state, reason) => { 222 console.info(`case stateChange called, state is ${state}, reason is ${reason}`); 223 if (reason == media.StateChangeReason.BACKGROUND) { 224 console.info(`case media.StateChangeReason.BACKGROUND`); 225 await avPlayer.release().then(() => { 226 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 227 } 228 console.info(`case state is ${state}`); 229 switch (state) { 230 case AV_PLAYER_STATE.INITIALIZED: 231 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.INITIALIZED); 232 avPlayer.surfaceId = surfaceID; 233 // step 1, 13: initialized -> prepared 234 toPreparePromise(avPlayer, playTest); 235 break; 236 case AV_PLAYER_STATE.PREPARED: 237 prepareCnt++; 238 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PREPARED); 239 checkPlayTest(avPlayer, playTest); 240 expect(avPlayer.currentTime).assertEqual(0); 241 if (prepareCnt == 1) { 242 // step 2: prepared -> playing 243 avPlayer.play().then(() => { 244 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 245 } else { 246 // step 14: prepared -> seek 247 avPlayer.seek(avPlayer.duration); 248 } 249 break; 250 case AV_PLAYER_STATE.PLAYING: 251 playCnt++; 252 if (playCnt == 1) { 253 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PLAYING); 254 // step 3: playing -> seek duration/3 255 await mediaTestBase.msleepAsync(playTime); 256 avPlayer.seek(avPlayer.duration / 3); 257 } else if (playCnt == 2) { 258 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PLAYING); 259 // step 7: playing -> seek duration when loop true 260 avPlayer.seek(avPlayer.duration, media.SeekMode.SEEK_NEXT_SYNC); 261 } else if (playCnt == 3) { 262 // step 10: playing -> stop 263 avPlayer.stop().then(() => { 264 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 265 } 266 break; 267 case AV_PLAYER_STATE.PAUSED: 268 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PAUSED); 269 // step 5: pause -> seek 0 270 avPlayer.loop = true; 271 avPlayer.seek(0, media.SeekMode.SEEK_NEXT_SYNC); 272 break; 273 case AV_PLAYER_STATE.COMPLETED: 274 completedCnt++; 275 expect(avPlayer.currentTime).assertEqual(avPlayer.duration); 276 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.COMPLETED); 277 if (completedCnt == 1) { 278 // step 9: completed -> play 279 avPlayer.play(); 280 } else { 281 // step 16: completed -> reset 282 avPlayer.reset().then(() => { 283 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.IDLE); 284 // step 17: reset -> release 285 avPlayer.release().then(() => { 286 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 287 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 288 } 289 break; 290 case AV_PLAYER_STATE.STOPPED: 291 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.STOPPED); 292 // step 11: stop -> reset 293 avPlayer.reset().then(() => { 294 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.IDLE); 295 // step 12: reset -> initialized 296 setSource(avPlayer, src); 297 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 298 break; 299 case AV_PLAYER_STATE.RELEASED: 300 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.RELEASED); 301 offCallback(avPlayer, ['stateChange', 'volumeChange', 'endOfStream', 'seekDone', 'speedDone', 302 'bitrateDone', 'timeUpdate', 'durationUpdate', 'bufferingUpdate', 'startRenderFrame', 'videoSizeChange', 303 'audioInterrupt', 'availableBitrates', 'error']); 304 // step 18: release -> done 305 avPlayer = null; 306 expect(volumeCnt[0]).assertLarger(0); 307 expect(endOfStreamCnt[0]).assertLarger(0); 308 expect(seekDoneCnt[0]).assertLarger(0); 309 expect(speedDoneCnt[0]).assertLarger(0); 310 expect(completedCnt).assertLarger(0); 311 if (playTest.width != 0) { 312 expect(startRenderFrameCnt[0]).assertLarger(0); 313 expect(videoSizeCnt[0]).assertLarger(0); 314 } else { 315 expect(startRenderFrameCnt[0]).assertEqual(0); 316 expect(videoSizeCnt[0]).assertEqual(0); 317 } 318 expect(durationUpdateCnt[0]).assertLarger(0) 319 done(); 320 break; 321 case AV_PLAYER_STATE.ERROR: 322 expect().assertFail(); 323 avPlayer.release().then(() => { 324 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 325 break; 326 default: 327 break; 328 } 329 }); 330 avPlayer.on('seekDone', async (seekDoneTime) => { 331 seekDoneCnt[0]++; 332 console.info(`case seekDone called, seekDoneCnt is ${seekDoneCnt}, seekDoneTime is ${seekDoneTime}`); 333 switch (seekDoneCnt[0]) { 334 case 2: 335 // step 6: seek(paused) -> play 336 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PAUSED); 337 avPlayer.play(); 338 avPlayer.setSpeed(media.PlaybackSpeed.SPEED_FORWARD_2_00_X); 339 avPlayer.setVolume(0.5); 340 break; 341 case 1: 342 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PLAYING); 343 // step 4: seek(playing) -> pause 344 avPlayer.pause().then(() => { 345 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 346 break; 347 case 3: 348 case 4: 349 case 5: 350 let nowTime = avPlayer.currentTime; 351 if (avPlayer.state == AV_PLAYER_STATE.PREPARED) { 352 // step 15: prepared -> play 353 avPlayer.play(); 354 } 355 if (nowTime > avPlayer.duration / 2) { 356 avPlayer.setSpeed(media.PlaybackSpeed.SPEED_FORWARD_1_00_X); 357 await mediaTestBase.msleepAsync(avPlayer.duration - nowTime + playTime); 358 } 359 if (avPlayer.loop == true) { 360 // step 8: playing -> seek duration when loop false 361 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PLAYING); 362 avPlayer.loop = false; 363 avPlayer.seek(avPlayer.duration, media.SeekMode.SEEK_NEXT_SYNC); 364 } 365 break; 366 } 367 }); 368 setCallback(avPlayer, 'volumeChange', volumeCnt); 369 setCallback(avPlayer, 'endOfStream', endOfStreamCnt); 370 setCallback(avPlayer, 'speedDone', speedDoneCnt); 371 setCallback(avPlayer, 'bitrateDone', null); 372 setCallback(avPlayer, 'timeUpdate', null); 373 setCallback(avPlayer, 'bufferingUpdate', null); 374 setCallback(avPlayer, 'durationUpdate', durationUpdateCnt); 375 setCallback(avPlayer, 'startRenderFrame', startRenderFrameCnt); 376 setCallback(avPlayer, 'videoSizeChange', videoSizeCnt); 377 setCallback(avPlayer, 'audioInterrupt', null); 378 setCallback(avPlayer, 'availableBitrates', null); 379 avPlayer.on('error', async (err) => { 380 console.error(`case error called, errMessage is ${err.message}`); 381 expect().assertFail(); 382 await avPlayer.release().then(() => { 383 avPlayer = null; 384 done(); 385 }); 386 }); 387} 388 389export async function testAVPlayerFun(src, avPlayer, playTest, playTime, done) { 390 console.info(`case media source: ${src}`) 391 await media.createAVPlayer().then((video) => { 392 if (typeof(video) != 'undefined') { 393 console.info('case createAVPlayer success'); 394 avPlayer = video; 395 } else { 396 console.error('case createAVPlayer failed'); 397 expect().assertFail(); 398 done(); 399 } 400 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 401 setAVPlayerFunCb(src, avPlayer, playTest, playTime, done); 402 setSource(avPlayer, src); 403} 404 405export function setAVPlayerSeekCb(src, avPlayer, playTest, playTime, done) { 406 let volumeCnt = [0]; 407 let endOfStreamCnt = 0; 408 let seekDoneCnt = 0; 409 let speedDoneCnt = [0]; 410 let playCnt = 0; 411 let surfaceID = globalThis.value; 412 console.info(`case setCallback in, surfaceID is ${surfaceID}`); 413 avPlayer.on('stateChange', async (state, reason) => { 414 console.info(`case stateChange called, state is ${state}, reason is ${reason}`); 415 if (reason == media.StateChangeReason.BACKGROUND) { 416 avPlayer.release().then(() => { 417 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 418 } 419 switch (state) { 420 case AV_PLAYER_STATE.INITIALIZED: 421 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.INITIALIZED); 422 avPlayer.surfaceId = surfaceID; 423 console.info('case initialized -> prepared'); 424 // step 1,10: initialized -> prepared 425 avPlayer.prepare((err) => { 426 avPlayer.loop = true; 427 if (err != null) { 428 console.error(`case prepare error, errMessage is ${err.message}`); 429 expect().assertFail(); 430 done(); 431 } else { 432 checkPlayTest(avPlayer, playTest); 433 } 434 }); 435 break; 436 case AV_PLAYER_STATE.PREPARED: 437 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PREPARED); 438 checkPlayTest(avPlayer, playTest); 439 expect(avPlayer.currentTime).assertEqual(0); 440 offCallback(avPlayer, ['volumeChange']); 441 // step 2,11: prepared -> seek 0 442 avPlayer.seek(0, 2); // 2: CLOSEST SYNC 443 break; 444 case AV_PLAYER_STATE.PLAYING: 445 playCnt++; 446 if (playCnt == 1) { 447 // step 4: seek + pause 448 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PLAYING); 449 avPlayer.seek(avPlayer.duration / 2, media.SeekMode.SEEK_PREV_SYNC); 450 // avPlayer.pause(); 451 avPlayer.pause((err) => { 452 if (err != null) { 453 mediaTestBase.assertErr('pause', err, done); 454 } 455 }); 456 } else if (playCnt == 3) { 457 // step 12: seek duration 458 avPlayer.seek(avPlayer.duration, media.SeekMode.SEEK_PREV_SYNC); 459 avPlayer.stop((err) => { 460 if (err == null) { 461 avPlayer.release((err) => { 462 if (err != null) { 463 mediaTestBase.assertErr('release', err, done); 464 } 465 }) 466 } else { 467 mediaTestBase.assertErr('stop', err, done); 468 } 469 }); 470 } 471 break; 472 case AV_PLAYER_STATE.RELEASED: 473 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.RELEASED); 474 // step 18: release -> done 475 avPlayer = null; 476 expect(volumeCnt[0]).assertEqual(0); 477 expect(endOfStreamCnt).assertLarger(0); 478 done(); 479 break; 480 case AV_PLAYER_STATE.ERROR: 481 expect().assertFail(); 482 avPlayer.release().then(() => { 483 }, mediaTestBase.failureCallback).catch(mediaTestBase.catchCallback); 484 break; 485 default: 486 break; 487 } 488 }); 489 490 avPlayer.on('endOfStream', () => { 491 console.info(`case endOfStream called`); 492 endOfStreamCnt++; 493 // step 9: seek + reset 494 avPlayer.seek(avPlayer.duration / 2, 3); // 3: CLOSEST 495 avPlayer.reset((err) => { 496 if (err == null) { 497 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.IDLE); 498 console.info('case reset success!!'); 499 setSource(avPlayer, src); 500 } else { 501 mediaTestBase.assertErr('reset', err, done); 502 } 503 }); 504 }); 505 avPlayer.on('seekDone', async (seekDoneTime) => { 506 seekDoneCnt++; 507 console.info(`case seekDone called, seekDoneCnt is ${seekDoneCnt}, seekDoneTime is ${seekDoneTime}`); 508 switch (seekDoneCnt) { 509 case 1: 510 expect(avPlayer.state).assertEqual(AV_PLAYER_STATE.PREPARED); 511 // step 3: seek(prepared) -> play 512 avPlayer.play((err) => { 513 if (err != null) { 514 mediaTestBase.assertErr('play', err, done); 515 } 516 }); 517 break; 518 case 2: 519 // step 5: seek + play 520 avPlayer.seek(avPlayer.duration / 2, media.SeekMode.SEEK_NEXT_SYNC); 521 avPlayer.play(); 522 break; 523 case 3: 524 // step 6: seek + setVolume 525 avPlayer.setVolume(0.5); 526 avPlayer.seek(avPlayer.duration / 2, media.SeekMode.SEEK_CLOSEST_SYNC); 527 avPlayer.play(); 528 break; 529 case 4: 530 // step 7: seek + seek 531 avPlayer.seek(avPlayer.duration / 2); 532 avPlayer.seek(avPlayer.duration, media.SeekMode.SEEK_NEXT_SYNC); 533 avPlayer.play(); 534 break; 535 case 5: 536 // step 8: seek duration 537 avPlayer.seek(avPlayer.duration, media.SeekMode.SEEK_PREV_SYNC); 538 break; 539 default: 540 avPlayer.play(); 541 break; 542 } 543 }); 544 setCallback(avPlayer, 'volumeChange', volumeCnt); 545 setCallback(avPlayer, 'speedDone', speedDoneCnt); 546 setCallback(avPlayer, 'bitrateDone', null); 547 setCallback(avPlayer, 'timeUpdate', null); 548 setCallback(avPlayer, 'bufferingUpdate', null); 549 setCallback(avPlayer, 'durationUpdate', null); 550 setCallback(avPlayer, 'startRenderFrame', null); 551 setCallback(avPlayer, 'videoSizeChange', null); 552 setCallback(avPlayer, 'audioInterrupt', null); 553 setCallback(avPlayer, 'availableBitrates', null); 554 avPlayer.on('error', async (err) => { 555 console.error(`case error called, errMessage is ${err.message}`); 556 }); 557} 558 559export async function testAVPlayerSeek(src, avPlayer, playTest, playTime, done) { 560 console.info(`case media source: ${src}`) 561 media.createAVPlayer((err, video) => { 562 console.info(`case media err: ${err}`) 563 if (typeof(video) != 'undefined') { 564 console.info('case createAVPlayer success'); 565 avPlayer = video; 566 setAVPlayerSeekCb(src, avPlayer, playTest, playTime, done); 567 setSource(avPlayer, src); 568 } 569 if (err != null) { 570 console.error(`case createAVPlayer error, errMessage is ${err.message}`); 571 expect().assertFail(); 572 done(); 573 } 574 }); 575} 576