1 /*
2 * Copyright (c) 2024 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
16 #include "audio_haptic_player_impl.h"
17 #include "audio_haptic_sound_normal_impl.h"
18
19 #include <fcntl.h>
20
21 #include "audio_haptic_log.h"
22 #include "directory_ex.h"
23 #include "media_errors.h"
24 #include "player.h"
25
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO_NAPI, "AudioHapticSoundNormalImpl"};
28 }
29
30 namespace OHOS {
31 namespace Media {
32 const int32_t LOAD_WAIT_SECONDS = 2;
33
AudioHapticSoundNormalImpl(const AudioSource & audioSource,const bool & muteAudio,const AudioStandard::StreamUsage & streamUsage)34 AudioHapticSoundNormalImpl::AudioHapticSoundNormalImpl(const AudioSource& audioSource, const bool &muteAudio,
35 const AudioStandard::StreamUsage &streamUsage)
36 : audioSource_(audioSource),
37 muteAudio_(muteAudio),
38 streamUsage_(streamUsage)
39 {
40 }
41
~AudioHapticSoundNormalImpl()42 AudioHapticSoundNormalImpl::~AudioHapticSoundNormalImpl()
43 {
44 if (avPlayer_ != nullptr) {
45 (void)ReleaseSoundInternal();
46 }
47 }
48
LoadAVPlayer()49 int32_t AudioHapticSoundNormalImpl::LoadAVPlayer()
50 {
51 avPlayer_ = PlayerFactory::CreatePlayer();
52 CHECK_AND_RETURN_RET_LOG(avPlayer_ != nullptr, MSERR_INVALID_VAL, "Failed to create AvPlayer instance");
53
54 avPlayerCallback_ = std::make_shared<AHSoundNormalCallback>(shared_from_this());
55 CHECK_AND_RETURN_RET_LOG(avPlayerCallback_ != nullptr, MSERR_INVALID_VAL, "Failed to create callback object");
56 avPlayer_->SetPlayerCallback(avPlayerCallback_);
57
58 configuredAudioSource_ = {};
59 playerState_ = AudioHapticPlayerState::STATE_NEW;
60 return MSERR_OK;
61 }
62
PrepareSound()63 int32_t AudioHapticSoundNormalImpl::PrepareSound()
64 {
65 MEDIA_LOGI("PrepareSound with AVPlayer");
66 std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
67 int32_t result = LoadAVPlayer();
68 CHECK_AND_RETURN_RET_LOG(result == MSERR_OK && avPlayer_ != nullptr, MSERR_INVALID_VAL,
69 "Audio haptic player(avplayer) instance is null");
70 CHECK_AND_RETURN_RET_LOG(!audioSource_.empty(), MSERR_OPEN_FILE_FAILED, "The audio source is empty");
71 if (audioSource_ != configuredAudioSource_) {
72 return ResetAVPlayer();
73 }
74 return MSERR_OK;
75 }
76
OpenAudioSource()77 int32_t AudioHapticSoundNormalImpl::OpenAudioSource()
78 {
79 if (fileDes_ != -1) {
80 (void)close(fileDes_);
81 fileDes_ = -1;
82 }
83
84 auto audioUri = audioSource_.audioUri;
85 auto audioFd = audioSource_.fd;
86 MEDIA_LOGI("Set audio source to avplayer. audioUri [%{public}s] audioFd: [%{public}d]",
87 audioUri.c_str(), audioFd);
88 CHECK_AND_RETURN_RET_LOG(!audioUri.empty() || audioFd > FILE_DESCRIPTOR_INVALID, MSERR_OPEN_FILE_FAILED,
89 "The audio uri is empty or the fd is invalid");
90
91 if (!audioUri.empty()) {
92 const std::string fdHead = "fd://";
93 if (audioUri.find(fdHead) != std::string::npos) {
94 int32_t fd = atoi(audioUri.substr(fdHead.size()).c_str());
95 CHECK_AND_RETURN_RET_LOG(fd > FILE_DESCRIPTOR_INVALID, MSERR_OPEN_FILE_FAILED,
96 "Prepare: Failed to extract fd for avplayer.");
97 fileDes_ = dup(fd);
98 } else {
99 std::string absFilePath;
100 CHECK_AND_RETURN_RET_LOG(PathToRealPath(audioUri, absFilePath), MSERR_OPEN_FILE_FAILED,
101 "file is not real path, file path: %{private}s", audioUri.c_str());
102 CHECK_AND_RETURN_RET_LOG(!absFilePath.empty(), MSERR_OPEN_FILE_FAILED,
103 "Failed to obtain the canonical path for source path %{public}d %{private}s",
104 errno, audioUri.c_str());
105 fileDes_ = open(absFilePath.c_str(), O_RDONLY | O_CLOEXEC);
106 }
107 } else {
108 fileDes_ = dup(audioFd);
109 }
110 MEDIA_LOGI("fileDes_ == %{public}d", fileDes_);
111 CHECK_AND_RETURN_RET_LOG(fileDes_ > FILE_DESCRIPTOR_INVALID, MSERR_OPEN_FILE_FAILED,
112 "Prepare: Invalid fileDes for avplayer.");
113 return MSERR_OK;
114 }
115
ResetAVPlayer()116 int32_t AudioHapticSoundNormalImpl::ResetAVPlayer()
117 {
118 // Reset the player and reload it.
119 MEDIA_LOGI("ResetAVPlayer");
120 (void)avPlayer_->Reset();
121 int32_t ret = OpenAudioSource();
122 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Failed to open audio source.");
123
124 ret = avPlayer_->SetSource(fileDes_, audioSource_.offset, audioSource_.length);
125 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_OPEN_FILE_FAILED, "Set source failed %{public}d", ret);
126
127 Format format;
128 format.PutIntValue(PlayerKeys::CONTENT_TYPE, AudioStandard::CONTENT_TYPE_UNKNOWN);
129 format.PutIntValue(PlayerKeys::STREAM_USAGE, streamUsage_);
130 ret = avPlayer_->SetParameter(format);
131 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Set stream usage to AVPlayer failed %{public}d", ret);
132
133 ret = avPlayer_->PrepareAsync();
134 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Prepare failed %{public}d", ret);
135
136 std::unique_lock<std::mutex> lockPrepare(prepareMutex_);
137 prepareCond_.wait_for(lockPrepare, std::chrono::seconds(LOAD_WAIT_SECONDS),
138 [this]() { return isPrepared_ || isReleased_ || isUnsupportedFile_; });
139 CHECK_AND_RETURN_RET_LOG(!isReleased_, MSERR_INVALID_OPERATION, "The avplayer is released when it is preparing.");
140 CHECK_AND_RETURN_RET_LOG(!isUnsupportedFile_, MSERR_UNSUPPORT_FILE, "Unsupported file when preparing avplayer.");
141 CHECK_AND_RETURN_RET_LOG(isPrepared_, MSERR_OPEN_FILE_FAILED, "Failed to load audio uri: time out.");
142
143 // The avplayer has been prepared.
144 float actualVolume = volume_ * (muteAudio_ ? 0 : 1);
145 MEDIA_LOGI("AVPlayer has been prepared. Set volume %{public}f and loop %{public}d.", actualVolume, loop_);
146 (void)avPlayer_->SetVolume(actualVolume, actualVolume);
147 (void)avPlayer_->SetLooping(loop_);
148
149 configuredAudioSource_ = audioSource_;
150 playerState_ = AudioHapticPlayerState::STATE_PREPARED;
151 return MSERR_OK;
152 }
153
154
StartSound(const int32_t & audioHapticSyncId)155 int32_t AudioHapticSoundNormalImpl::StartSound(const int32_t &audioHapticSyncId)
156 {
157 MEDIA_LOGI("StartSound with AVPlayer");
158 std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
159 CHECK_AND_RETURN_RET_LOG(avPlayer_ != nullptr && playerState_ != AudioHapticPlayerState::STATE_INVALID,
160 MSERR_INVALID_VAL, "StartAVPlayer: no available AVPlayer_");
161 CHECK_AND_RETURN_RET_LOG(!audioSource_.empty(), MSERR_OPEN_FILE_FAILED, "The audio source is invalid");
162
163 if (playerState_ == AudioHapticPlayerState::STATE_RUNNING) {
164 MEDIA_LOGE("The avplayer has been running. Cannot start again");
165 AudioHapticPlayerImpl::SendHapticPlayerEvent(MSERR_START_FAILED, "AVPLAYER_STATE_RUNNING");
166 return MSERR_START_FAILED;
167 }
168
169 int32_t ret = MSERR_OK;
170 // Player doesn't support play in stopped state. Hence reinitialise player for making start<-->stop to work
171 if (playerState_ == AudioHapticPlayerState::STATE_STOPPED || audioSource_ != configuredAudioSource_) {
172 ret = ResetAVPlayer();
173 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "ResetAVPlayer failed %{public}d", ret);
174 }
175
176 audioHapticSyncId_ = audioHapticSyncId;
177 Format format;
178 format.PutIntValue(PlayerKeys::PLAYER_AUDIO_HAPTICS_SYNC_ID, audioHapticSyncId_);
179 ret = avPlayer_->SetParameter(format);
180 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Set stream usage to AVPlayer failed %{public}d", ret);
181
182 ret = avPlayer_->Play();
183 AudioHapticPlayerImpl::SendHapticPlayerEvent(ret, "AVPLAYER_START_FAILED");
184 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_START_FAILED, "Start failed %{public}d", ret);
185
186 playerState_ = AudioHapticPlayerState::STATE_RUNNING;
187 return MSERR_OK;
188 }
189
StopSound()190 int32_t AudioHapticSoundNormalImpl::StopSound()
191 {
192 MEDIA_LOGI("StopSound with AVPlayer");
193 std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
194 CHECK_AND_RETURN_RET_LOG(avPlayer_ != nullptr && playerState_ != AudioHapticPlayerState::STATE_INVALID,
195 MSERR_INVALID_VAL, "StopAVPlayer: no available AVPlayer_");
196
197 if (playerState_ != AudioHapticPlayerState::STATE_STOPPED) {
198 (void)avPlayer_->Stop();
199 }
200
201 playerState_ = AudioHapticPlayerState::STATE_STOPPED;
202 return MSERR_OK;
203 }
204
ReleaseSound()205 int32_t AudioHapticSoundNormalImpl::ReleaseSound()
206 {
207 MEDIA_LOGI("ReleaseSound with AVPlayer");
208 return ReleaseSoundInternal();
209 }
210
ReleaseSoundInternal()211 int32_t AudioHapticSoundNormalImpl::ReleaseSoundInternal()
212 {
213 MEDIA_LOGI("Enter ReleaseSoundInternal().");
214 {
215 std::lock_guard<std::mutex> lockPrepare(prepareMutex_);
216 isReleased_ = true;
217 prepareCond_.notify_one();
218 }
219 std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
220 CHECK_AND_RETURN_RET_LOG(playerState_ != AudioHapticPlayerState::STATE_RELEASED, MSERR_OK,
221 "The audio haptic player for normal mode has been released.");
222 ReleaseAVPlayer();
223 playerState_ = AudioHapticPlayerState::STATE_RELEASED;
224 return MSERR_OK;
225 }
226
ReleaseAVPlayer()227 void AudioHapticSoundNormalImpl::ReleaseAVPlayer()
228 {
229 if (avPlayer_ != nullptr) {
230 (void)avPlayer_->Release();
231 avPlayer_ = nullptr;
232 }
233 avPlayerCallback_ = nullptr;
234 if (fileDes_ != -1) {
235 (void)close(fileDes_);
236 fileDes_ = -1;
237 }
238 }
239
SetVolume(float volume)240 int32_t AudioHapticSoundNormalImpl::SetVolume(float volume)
241 {
242 MEDIA_LOGI("AudioHapticSoundNormalImpl::SetVolume %{public}f", volume);
243 if (volume < 0.0f || volume > 1.0f) {
244 MEDIA_LOGE("SetVolume: the volume value is invalid.");
245 return MSERR_INVALID_VAL;
246 }
247
248 std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
249 int32_t result = MSERR_OK;
250 volume_ = volume;
251
252 if (playerState_ != AudioHapticPlayerState::STATE_PREPARED &&
253 playerState_ != AudioHapticPlayerState::STATE_RUNNING) {
254 MEDIA_LOGI("Audio haptic player is not prepared or running. No need to modify player");
255 return result;
256 }
257
258 float actualVolume = volume_ * (muteAudio_ ? 0 : 1);
259 result = avPlayer_->SetVolume(actualVolume, actualVolume);
260 return result;
261 }
262
SetLoop(bool loop)263 int32_t AudioHapticSoundNormalImpl::SetLoop(bool loop)
264 {
265 MEDIA_LOGI("AudioHapticSoundNormalImpl::SetLoop %{public}d", loop);
266 std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
267 int32_t result = MSERR_OK;
268 loop_ = loop;
269
270 if (playerState_ != AudioHapticPlayerState::STATE_PREPARED &&
271 playerState_ != AudioHapticPlayerState::STATE_RUNNING) {
272 MEDIA_LOGI("Audio haptic player is not prepared or running. No need to modify player");
273 return result;
274 }
275
276 result = avPlayer_->SetLooping(loop_);
277 return result;
278 }
279
GetAudioCurrentTime()280 int32_t AudioHapticSoundNormalImpl::GetAudioCurrentTime()
281 {
282 if (avPlayer_ == nullptr) {
283 MEDIA_LOGE("GetAudioCurrentTime: avPlayer_ is nullptr. This function is only usable for avPlayer.");
284 return -1;
285 }
286 int32_t currentTime = -1;
287 (void)avPlayer_->GetCurrentTime(currentTime);
288 return currentTime;
289 }
290
SetAudioHapticSoundCallback(const std::shared_ptr<AudioHapticSoundCallback> & callback)291 int32_t AudioHapticSoundNormalImpl::SetAudioHapticSoundCallback(
292 const std::shared_ptr<AudioHapticSoundCallback> &callback)
293 {
294 if (callback == nullptr) {
295 MEDIA_LOGE("The audio haptic player callback is nullptr.");
296 return MSERR_INVALID_VAL;
297 }
298
299 std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
300 audioHapticPlayerCallback_ = callback;
301 return MSERR_OK;
302 }
303
SetAVPlayerState(AudioHapticPlayerState playerState)304 void AudioHapticSoundNormalImpl::SetAVPlayerState(AudioHapticPlayerState playerState)
305 {
306 MEDIA_LOGI("SetAVPlayerState, state %{public}d", playerState);
307 playerState_ = playerState;
308 }
309
NotifyPreparedEvent()310 void AudioHapticSoundNormalImpl::NotifyPreparedEvent()
311 {
312 std::lock_guard<std::mutex> lockPrepare(prepareMutex_);
313 isPrepared_ = true;
314 prepareCond_.notify_one();
315 }
316
NotifyErrorEvent(int32_t errorCode)317 void AudioHapticSoundNormalImpl::NotifyErrorEvent(int32_t errorCode)
318 {
319 MediaServiceErrCode mediaErr = static_cast<MediaServiceErrCode>(errorCode);
320 if (mediaErr == MSERR_UNSUPPORT_FILE) {
321 std::lock_guard<std::mutex> lockPrepare(prepareMutex_);
322 isUnsupportedFile_ = true;
323 prepareCond_.notify_one();
324 }
325
326 std::shared_ptr<AudioHapticSoundCallback> cb = audioHapticPlayerCallback_.lock();
327 if (cb != nullptr) {
328 MEDIA_LOGI("NotifyFirstFrameEvent for audio haptic player");
329 cb->OnError(errorCode);
330 } else {
331 MEDIA_LOGE("NotifyFirstFrameEvent: audioHapticPlayerCallback_ is nullptr");
332 }
333 }
334
NotifyFirstFrameEvent(uint64_t latency)335 void AudioHapticSoundNormalImpl::NotifyFirstFrameEvent(uint64_t latency)
336 {
337 std::shared_ptr<AudioHapticSoundCallback> cb = audioHapticPlayerCallback_.lock();
338 if (cb != nullptr) {
339 MEDIA_LOGI("NotifyFirstFrameEvent for audio haptic player");
340 cb->OnFirstFrameWriting(latency);
341 } else {
342 MEDIA_LOGE("NotifyFirstFrameEvent: audioHapticPlayerCallback_ is nullptr");
343 }
344 }
345
NotifyInterruptEvent(AudioStandard::InterruptEvent & interruptEvent)346 void AudioHapticSoundNormalImpl::NotifyInterruptEvent(AudioStandard::InterruptEvent &interruptEvent)
347 {
348 std::shared_ptr<AudioHapticSoundCallback> cb = audioHapticPlayerCallback_.lock();
349 if (cb != nullptr) {
350 MEDIA_LOGI("NotifyInterruptEvent for audio haptic player");
351 cb->OnInterrupt(interruptEvent);
352 } else {
353 MEDIA_LOGE("NotifyInterruptEvent: audioHapticPlayerCallback_ is nullptr");
354 }
355 }
356
NotifyEndOfStreamEvent(const bool & isLoop)357 void AudioHapticSoundNormalImpl::NotifyEndOfStreamEvent(const bool &isLoop)
358 {
359 MEDIA_LOGI("NotifyEndOfStreamEvent");
360 if (!isLoop) {
361 playerState_ = AudioHapticPlayerState::STATE_STOPPED;
362 }
363 std::shared_ptr<AudioHapticSoundCallback> cb = audioHapticPlayerCallback_.lock();
364 if (cb != nullptr) {
365 MEDIA_LOGI("NotifyEndOfStreamEvent for audio haptic player");
366 cb->OnEndOfStream();
367 } else {
368 MEDIA_LOGE("NotifyEndOfStreamEvent: audioHapticPlayerCallback_ is nullptr");
369 }
370 }
371
372 // Callback class symbols
AHSoundNormalCallback(std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl)373 AHSoundNormalCallback::AHSoundNormalCallback(std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl)
374 : soundNormalImpl_(soundNormalImpl) {}
375
OnError(int32_t errorCode,const std::string & errorMsg)376 void AHSoundNormalCallback::OnError(int32_t errorCode, const std::string &errorMsg)
377 {
378 MEDIA_LOGE("OnError reported from AVPlayer: %{public}d", errorCode);
379 std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
380 if (soundNormalImpl == nullptr) {
381 MEDIA_LOGE("The audio haptic player for normal mode has been released.");
382 return;
383 }
384 soundNormalImpl->NotifyErrorEvent(errorCode);
385 }
386
OnInfo(Media::PlayerOnInfoType type,int32_t extra,const Media::Format & infoBody)387 void AHSoundNormalCallback::OnInfo(Media::PlayerOnInfoType type, int32_t extra, const Media::Format &infoBody)
388 {
389 if (type == INFO_TYPE_STATE_CHANGE) {
390 MEDIA_LOGI("OnInfo: state change reported from AVPlayer.");
391 HandleStateChangeEvent(extra, infoBody);
392 } else if (type == INFO_TYPE_INTERRUPT_EVENT) {
393 MEDIA_LOGI("OnInfo: interrupt event reported from AVPlayer.");
394 HandleAudioInterruptEvent(extra, infoBody);
395 } else if (type == INFO_TYPE_AUDIO_FIRST_FRAME) {
396 MEDIA_LOGI("OnInfo: first frame event reported from AVPlayer.");
397 HandleAudioFirstFrameEvent(extra, infoBody);
398 } else if (type == INFO_TYPE_EOS) {
399 HandleEOSEvent(extra, infoBody);
400 } else {
401 return;
402 }
403 }
404
HandleStateChangeEvent(int32_t extra,const Format & infoBody)405 void AHSoundNormalCallback::HandleStateChangeEvent(int32_t extra, const Format &infoBody)
406 {
407 MEDIA_LOGI("HandleStateChangeEvent from AVPlayer");
408 PlayerStates avPlayerState = static_cast<PlayerStates>(extra);
409 switch (avPlayerState) {
410 case PLAYER_STATE_ERROR:
411 playerState_ = AudioHapticPlayerState::STATE_INVALID;
412 break;
413 case PLAYER_IDLE:
414 case PLAYER_INITIALIZED:
415 case PLAYER_PREPARING:
416 playerState_ = AudioHapticPlayerState::STATE_NEW;
417 break;
418 case PLAYER_PREPARED:
419 playerState_ = AudioHapticPlayerState::STATE_PREPARED;
420 break;
421 case PLAYER_STARTED:
422 playerState_ = AudioHapticPlayerState::STATE_RUNNING;
423 break;
424 case PLAYER_PAUSED:
425 playerState_ = AudioHapticPlayerState::STATE_PAUSED;
426 break;
427 case PLAYER_STOPPED:
428 case PLAYER_PLAYBACK_COMPLETE:
429 playerState_ = AudioHapticPlayerState::STATE_STOPPED;
430 break;
431 default:
432 break;
433 }
434 std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
435 if (soundNormalImpl == nullptr) {
436 MEDIA_LOGE("The audio haptic player for normal mode has been released.");
437 return;
438 }
439 soundNormalImpl->SetAVPlayerState(playerState_);
440
441 if (avPlayerState == PLAYER_PREPARED) {
442 soundNormalImpl->NotifyPreparedEvent();
443 }
444 }
445
HandleAudioInterruptEvent(int32_t extra,const Format & infoBody)446 void AHSoundNormalCallback::HandleAudioInterruptEvent(int32_t extra, const Format &infoBody)
447 {
448 MEDIA_LOGI("HandleAudioInterruptEvent from AVPlayer");
449 AudioStandard::InterruptEvent interruptEvent;
450 int32_t eventTypeValue = 0;
451 int32_t forceTypeValue = 0;
452 int32_t hintTypeValue = 0;
453 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventTypeValue);
454 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceTypeValue);
455 (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintTypeValue);
456 interruptEvent.eventType = static_cast<AudioStandard::InterruptType>(eventTypeValue);
457 interruptEvent.forceType = static_cast<AudioStandard::InterruptForceType>(forceTypeValue);
458 interruptEvent.hintType = static_cast<AudioStandard::InterruptHint>(hintTypeValue);
459
460 std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
461 if (soundNormalImpl == nullptr) {
462 MEDIA_LOGE("The audio haptic player for normal mode has been released.");
463 return;
464 }
465 soundNormalImpl->NotifyInterruptEvent(interruptEvent);
466 }
467
HandleAudioFirstFrameEvent(int32_t extra,const Format & infoBody)468 void AHSoundNormalCallback::HandleAudioFirstFrameEvent(int32_t extra, const Format &infoBody)
469 {
470 int64_t value = 0;
471 (void)infoBody.GetLongValue(PlayerKeys::AUDIO_FIRST_FRAME, value);
472 uint64_t latency = static_cast<uint64_t>(value);
473 MEDIA_LOGI("HandleAudioFirstFrameEvent from AVPlayer. Latency %{public}" PRIu64 "", latency);
474 std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
475 if (soundNormalImpl == nullptr) {
476 MEDIA_LOGE("The audio haptic player for normal mode has been released.");
477 return;
478 }
479 soundNormalImpl->NotifyFirstFrameEvent(latency);
480 }
481
HandleEOSEvent(int32_t extra,const Format & infoBody)482 void AHSoundNormalCallback::HandleEOSEvent(int32_t extra, const Format &infoBody)
483 {
484 MEDIA_LOGI("AHSoundNormalCallback::HandleEOSEvent from AVPlayer");
485
486 std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
487 if (soundNormalImpl == nullptr) {
488 MEDIA_LOGE("The audio haptic player for normal mode has been released.");
489 return;
490 }
491 soundNormalImpl->NotifyEndOfStreamEvent(static_cast<bool>(extra));
492 }
493
494 } // namesapce AudioStandard
495 } // namespace OHOS