1 /*
2 * Copyright (c) 2020-2021 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 #include "audio_module.h"
16 #include "media_log.h"
17
18 namespace OHOS {
19 namespace ACELite {
20 constexpr char PROP_SUCCESS[] = "success";
21 constexpr char PROP_COMPLETE[] = "complete";
22
OnTerminate()23 void AudioModule::OnTerminate()
24 {
25 AudioPlayer *audioPlayer = AudioPlayer::GetInstance();
26 if (audioPlayer == nullptr) {
27 MEDIA_ERR_LOG("audio player is null");
28 return;
29 }
30 audioPlayer->DestoryPlayer();
31 audioPlayer->ReleaseEventListeners();
32 audioPlayer->StopUpdateTimeThread();
33 }
34
DefineProperty(JSIValue target,const char * propName,JSIFunctionHandler getter,JSIFunctionHandler setter)35 void AudioModule::DefineProperty(JSIValue target,
36 const char *propName,
37 JSIFunctionHandler getter,
38 JSIFunctionHandler setter)
39 {
40 JSPropertyDescriptor descriptor;
41 descriptor.getter = getter;
42 descriptor.setter = setter;
43 JSI::DefineNamedProperty(target, propName, descriptor);
44 }
45
Play(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)46 JSIValue AudioModule::Play(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
47 {
48 return JSI::CreateBoolean(AudioPlayer::GetInstance()->Play());
49 }
50
Pause(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)51 JSIValue AudioModule::Pause(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
52 {
53 return JSI::CreateBoolean(AudioPlayer::GetInstance()->Pause());
54 }
55
Stop(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)56 JSIValue AudioModule::Stop(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
57 {
58 return JSI::CreateBoolean(AudioPlayer::GetInstance()->Stop());
59 }
60
GetPlayState(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)61 JSIValue AudioModule::GetPlayState(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
62 {
63 if (argsSize < 1) {
64 MEDIA_ERR_LOG("1 argument is required.");
65 return JSI::CreateBoolean(false);
66 }
67
68 JSIValue options = args[0];
69 if (!JSI::ValueIsObject(options)) {
70 MEDIA_ERR_LOG("invalid parameter.");
71 return JSI::CreateBoolean(false);
72 }
73
74 JSIValue successCallback = JSI::GetNamedProperty(options, PROP_SUCCESS);
75 if (!JSI::ValueIsUndefined(successCallback)) {
76 AudioPlayer *audioPlayer = AudioPlayer::GetInstance();
77 JSIValue data = JSI::CreateObject();
78 JSI::SetStringProperty(data, "status", audioPlayer->GetStatus());
79 JSI::SetStringProperty(data, "src", audioPlayer->GetSrc());
80 JSI::SetNumberProperty(data, "currentTime", audioPlayer->GetCurrentTime());
81 JSI::SetBooleanProperty(data, "autoplay", audioPlayer->GetAutoPlay());
82 JSI::SetBooleanProperty(data, "loop", audioPlayer->IsLooping());
83 JSI::SetNumberProperty(data, "volume", audioPlayer->GetVolume());
84 JSI::SetBooleanProperty(data, "muted", audioPlayer->IsMuted());
85 JSIValue params[1] = { data };
86 JSI::CallFunction(successCallback, thisVal, params, 1);
87 JSI::ReleaseValue(successCallback);
88 }
89
90 JSIValue completeCallback = JSI::GetNamedProperty(options, PROP_COMPLETE);
91 if (!JSI::ValueIsUndefined(completeCallback)) {
92 JSI::CallFunction(completeCallback, thisVal, nullptr, 0);
93 JSI::ReleaseValue(completeCallback);
94 }
95
96 return JSI::CreateUndefined();
97 }
98
SrcGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)99 JSIValue AudioModule::SrcGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
100 {
101 char *src = AudioPlayer::GetInstance()->GetSrc();
102 return (src == nullptr) ? JSI::CreateUndefined() : JSI::CreateString(src);
103 }
104
SrcSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)105 JSIValue AudioModule::SrcSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
106 {
107 if (argsSize < 1) {
108 MEDIA_ERR_LOG("1 argument is required.");
109 return JSI::CreateBoolean(false);
110 }
111 char *src = JSI::ValueToString(args[0]);
112 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetSrc(src));
113 }
114
CurrentTimeGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)115 JSIValue AudioModule::CurrentTimeGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
116 {
117 return JSI::CreateNumber(AudioPlayer::GetInstance()->GetCurrentTime());
118 }
119
CurrentTimeSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)120 JSIValue AudioModule::CurrentTimeSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
121 {
122 if (argsSize < 1) {
123 MEDIA_ERR_LOG("1 argument is required.");
124 return JSI::CreateBoolean(false);
125 }
126
127 int64_t currentTime = static_cast<int64_t>(JSI::ValueToNumber(args[0]));
128 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetCurrentTime(currentTime));
129 }
130
DurationGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)131 JSIValue AudioModule::DurationGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
132 {
133 int64_t duation = AudioPlayer::GetInstance()->GetDuration();
134 return duation == -1 ? JSI::CreateNumberNaN() : JSI::CreateNumber(static_cast<double>(duation));
135 }
136
DurationSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)137 JSIValue AudioModule::DurationSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
138 {
139 return JSI::CreateError(JsiErrorType::JSI_ERROR_COMMON, "duration is readonly.");
140 }
141
AutoPlayGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)142 JSIValue AudioModule::AutoPlayGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
143 {
144 return JSI::CreateBoolean(AudioPlayer::GetInstance()->GetAutoPlay());
145 }
146
AutoPlaySetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)147 JSIValue AudioModule::AutoPlaySetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
148 {
149 if (argsSize < 1) {
150 MEDIA_ERR_LOG("1 argument is required.");
151 return JSI::CreateBoolean(false);
152 }
153 bool autoPlay = JSI::ValueToBoolean(args[0]);
154 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetAutoPlay(autoPlay));
155 }
156
LoopGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)157 JSIValue AudioModule::LoopGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
158 {
159 return JSI::CreateBoolean(AudioPlayer::GetInstance()->IsLooping());
160 }
161
LoopSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)162 JSIValue AudioModule::LoopSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
163 {
164 if (argsSize < 1) {
165 MEDIA_ERR_LOG("1 argument is required.");
166 return JSI::CreateBoolean(false);
167 }
168
169 bool loop = JSI::ValueToBoolean(args[0]);
170 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetLoop(loop));
171 }
172
VolumeGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)173 JSIValue AudioModule::VolumeGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
174 {
175 return JSI::CreateNumber(AudioPlayer::GetInstance()->GetVolume());
176 }
177
VolumeSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)178 JSIValue AudioModule::VolumeSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
179 {
180 if (argsSize < 1) {
181 MEDIA_ERR_LOG("1 argument is required.");
182 return JSI::CreateBoolean(false);
183 }
184 float volume = static_cast<float>(JSI::ValueToNumber(args[0]));
185 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetVolume(volume));
186 }
187
MutedGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)188 JSIValue AudioModule::MutedGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
189 {
190 return JSI::CreateBoolean(AudioPlayer::GetInstance()->IsMuted());
191 }
192
MutedSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)193 JSIValue AudioModule::MutedSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
194 {
195 if (argsSize < 1) {
196 MEDIA_ERR_LOG("1 argument is required.");
197 return JSI::CreateBoolean(false);
198 }
199 bool muted = JSI::ValueToBoolean(args[0]);
200 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetMuted(muted));
201 }
202
OnPlayGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)203 JSIValue AudioModule::OnPlayGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
204 {
205 return GetEventCallback(AudioPlayer::GetInstance()->GetOnPlayListener());
206 }
207
OnPlaySetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)208 JSIValue AudioModule::OnPlaySetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
209 {
210 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
211 if (listener == nullptr) {
212 return JSI::CreateBoolean(false);
213 }
214 AudioPlayer::GetInstance()->SetOnPlayListener(listener);
215 return JSI::CreateBoolean(true);
216 }
217
OnPauseGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)218 JSIValue AudioModule::OnPauseGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
219 {
220 return GetEventCallback(AudioPlayer::GetInstance()->GetOnPauseListener());
221 }
222
OnPauseSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)223 JSIValue AudioModule::OnPauseSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
224 {
225 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
226 if (listener == nullptr) {
227 return JSI::CreateBoolean(false);
228 }
229 AudioPlayer::GetInstance()->SetOnPauseListener(listener);
230 return JSI::CreateBoolean(true);
231 }
232
OnStopGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)233 JSIValue AudioModule::OnStopGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
234 {
235 return GetEventCallback(AudioPlayer::GetInstance()->GetOnStopListener());
236 }
237
OnStopSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)238 JSIValue AudioModule::OnStopSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
239 {
240 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
241 if (listener == nullptr) {
242 return JSI::CreateBoolean(false);
243 }
244 AudioPlayer::GetInstance()->SetOnStopListener(listener);
245 return JSI::CreateBoolean(true);
246 }
247
OnLoadedDataGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)248 JSIValue AudioModule::OnLoadedDataGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
249 {
250 return GetEventCallback(AudioPlayer::GetInstance()->GetOnLoadedDataListener());
251 }
252
OnLoadedDataSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)253 JSIValue AudioModule::OnLoadedDataSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
254 {
255 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
256 if (listener == nullptr) {
257 return JSI::CreateBoolean(false);
258 }
259 AudioPlayer::GetInstance()->SetOnLoadedDataListener(listener);
260 return JSI::CreateBoolean(true);
261 }
262
OnEndedGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)263 JSIValue AudioModule::OnEndedGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
264 {
265 return GetEventCallback(AudioPlayer::GetInstance()->GetOnEndedListener());
266 }
267
OnEndedSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)268 JSIValue AudioModule::OnEndedSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
269 {
270 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
271 if (listener == nullptr) {
272 return JSI::CreateBoolean(false);
273 }
274 AudioPlayer::GetInstance()->SetOnEndedListener(listener);
275 return JSI::CreateBoolean(true);
276 }
277
OnErrorGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)278 JSIValue AudioModule::OnErrorGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
279 {
280 return GetEventCallback(AudioPlayer::GetInstance()->GetOnErrorListener());
281 }
282
OnErrorSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)283 JSIValue AudioModule::OnErrorSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
284 {
285 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
286 if (listener == nullptr) {
287 return JSI::CreateBoolean(false);
288 }
289 AudioPlayer::GetInstance()->SetOnErrorListener(listener);
290 return JSI::CreateBoolean(true);
291 }
292
OnTimeUpdateGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)293 JSIValue AudioModule::OnTimeUpdateGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
294 {
295 return GetEventCallback(AudioPlayer::GetInstance()->GetOnTimeUpdateListener());
296 }
297
OnTimeUpdateSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)298 JSIValue AudioModule::OnTimeUpdateSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
299 {
300 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
301 if (listener == nullptr) {
302 return JSI::CreateBoolean(false);
303 }
304 AudioPlayer::GetInstance()->SetOnTimeUpdateListener(listener);
305 return JSI::CreateBoolean(true);
306 }
307
GetEventCallback(const AudioEventListener * listener)308 JSIValue AudioModule::GetEventCallback(const AudioEventListener *listener)
309 {
310 return (listener == nullptr) ? JSI::CreateUndefined() : listener->GetCallback();
311 }
312
CreateAudioEventListener(const JSIValue * args,uint8_t argsSize)313 AudioEventListener *AudioModule::CreateAudioEventListener(const JSIValue *args, uint8_t argsSize)
314 {
315 if (argsSize < 1) {
316 MEDIA_ERR_LOG("1 argument is required.");
317 return nullptr;
318 }
319
320 JSIValue callback = args[0];
321 if (!JSI::ValueIsFunction(callback)) {
322 MEDIA_ERR_LOG("a function is required.");
323 return nullptr;
324 }
325
326 AudioEventListener *listener = new AudioEventListener(callback);
327 if (listener == nullptr) {
328 MEDIA_ERR_LOG("out of memory.");
329 }
330
331 return listener;
332 }
333
InitAudioModule(JSIValue exports)334 void InitAudioModule(JSIValue exports)
335 {
336 AudioPlayer::GetInstance()->CreatePlayer();
337 AudioPlayer::GetInstance()->ForkUpdateTimeThread();
338
339 JSI::SetOnTerminate(exports, AudioModule::OnTerminate);
340 JSI::SetModuleAPI(exports, "play", AudioModule::Play);
341 JSI::SetModuleAPI(exports, "pause", AudioModule::Pause);
342 JSI::SetModuleAPI(exports, "stop", AudioModule::Stop);
343 JSI::SetModuleAPI(exports, "getPlayState", AudioModule::GetPlayState);
344
345 AudioModule::DefineProperty(exports, "src", AudioModule::SrcGetter, AudioModule::SrcSetter);
346 AudioModule::DefineProperty(exports, "currentTime", AudioModule::CurrentTimeGetter, AudioModule::CurrentTimeSetter);
347 AudioModule::DefineProperty(exports, "duration", AudioModule::DurationGetter, AudioModule::DurationSetter);
348 AudioModule::DefineProperty(exports, "autoplay", AudioModule::AutoPlayGetter, AudioModule::AutoPlaySetter);
349 AudioModule::DefineProperty(exports, "loop", AudioModule::LoopGetter, AudioModule::LoopSetter);
350 AudioModule::DefineProperty(exports, "volume", AudioModule::VolumeGetter, AudioModule::VolumeSetter);
351 AudioModule::DefineProperty(exports, "muted", AudioModule::MutedGetter, AudioModule::MutedSetter);
352
353 AudioModule::DefineProperty(exports, "onplay", AudioModule::OnPlayGetter, AudioModule::OnPlaySetter);
354 AudioModule::DefineProperty(exports, "onpause", AudioModule::OnPauseGetter, AudioModule::OnPauseSetter);
355 AudioModule::DefineProperty(exports, "onstop", AudioModule::OnStopGetter, AudioModule::OnStopSetter);
356 AudioModule::DefineProperty(exports, "onloadeddata", AudioModule::OnLoadedDataGetter,
357 AudioModule::OnLoadedDataSetter);
358 AudioModule::DefineProperty(exports, "onended", AudioModule::OnEndedGetter, AudioModule::OnEndedSetter);
359 AudioModule::DefineProperty(exports, "onerror", AudioModule::OnErrorGetter, AudioModule::OnErrorSetter);
360 AudioModule::DefineProperty(exports, "ontimeupdate", AudioModule::OnTimeUpdateGetter,
361 AudioModule::OnTimeUpdateSetter);
362 }
363 } // namespace ACELite
364 } // namespace OHOS