• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #ifndef AV_PLAYER_NAPI_H
17 #define AV_PLAYER_NAPI_H
18 
19 #include "player.h"
20 #include "media_errors.h"
21 #include "napi/native_api.h"
22 #include "napi/native_node_api.h"
23 #include "avplayer_callback.h"
24 #include "common_napi.h"
25 #include "audio_info.h"
26 #include "task_queue.h"
27 
28 namespace OHOS {
29 namespace Media {
30 namespace AVPlayerState {
31 const std::string STATE_IDLE = "idle";
32 const std::string STATE_INITIALIZED = "initialized";
33 const std::string STATE_PREPARED = "prepared";
34 const std::string STATE_PLAYING = "playing";
35 const std::string STATE_PAUSED = "paused";
36 const std::string STATE_STOPPED = "stopped";
37 const std::string STATE_RELEASED = "released";
38 const std::string STATE_ERROR = "error";
39 const std::string STATE_COMPLETED = "completed";
40 }
41 
42 namespace AVPlayerEvent {
43 const std::string EVENT_STATE_CHANGE = "stateChange";
44 const std::string EVENT_VOLUME_CHANGE = "volumeChange";
45 const std::string EVENT_END_OF_STREAM = "endOfStream";
46 const std::string EVENT_SEEK_DONE = "seekDone";
47 const std::string EVENT_SPEED_DONE = "speedDone";
48 const std::string EVENT_BITRATE_DONE = "bitrateDone";
49 const std::string EVENT_TIME_UPDATE = "timeUpdate";
50 const std::string EVENT_DURATION_UPDATE = "durationUpdate";
51 const std::string EVENT_BUFFERING_UPDATE = "bufferingUpdate";
52 const std::string EVENT_START_RENDER_FRAME = "startRenderFrame";
53 const std::string EVENT_VIDEO_SIZE_CHANGE = "videoSizeChange";
54 const std::string EVENT_AUDIO_INTERRUPT = "audioInterrupt";
55 const std::string EVENT_AVAILABLE_BITRATES = "availableBitrates";
56 const std::string EVENT_ERROR = "error";
57 }
58 
59 using TaskRet = std::pair<int32_t, std::string>;
60 
61 class AVPlayerNapi : public AVPlayerNotify {
62 public:
63     __attribute__((visibility("default"))) static napi_value Init(napi_env env, napi_value exports);
64 
65 private:
66     static napi_value Constructor(napi_env env, napi_callback_info info);
67     static void Destructor(napi_env env, void *nativeObject, void *finalize);
68     /**
69      * createAVPlayer(callback: AsyncCallback<VideoPlayer>): void
70      * createAVPlayer(): Promise<VideoPlayer>
71      */
72     static napi_value JsCreateAVPlayer(napi_env env, napi_callback_info info);
73     /**
74      * prepare(callback: AsyncCallback<void>): void
75      * prepare(): Promise<void>
76      */
77     static napi_value JsPrepare(napi_env env, napi_callback_info info);
78     /**
79      * play(callback: AsyncCallback<void>): void
80      * play(): Promise<void>
81      */
82     static napi_value JsPlay(napi_env env, napi_callback_info info);
83     /**
84      * pause(callback: AsyncCallback<void>): void
85      * pause(): Promise<void>
86      */
87     static napi_value JsPause(napi_env env, napi_callback_info info);
88     /**
89      * stop(callback: AsyncCallback<void>): void
90      * stop(): Promise<void>
91      */
92     static napi_value JsStop(napi_env env, napi_callback_info info);
93     /**
94      * reset(callback: AsyncCallback<void>): void
95      * reset(): Promise<void>
96      */
97     static napi_value JsReset(napi_env env, napi_callback_info info);
98     /**
99      * release(callback: AsyncCallback<void>): void
100      * release(): Promise<void>
101      */
102     static napi_value JsRelease(napi_env env, napi_callback_info info);
103     /**
104      * seek(timeMs: number, mode?:SeekMode): void
105      */
106     static napi_value JsSeek(napi_env env, napi_callback_info info);
107     /**
108      * setSpeed(speed: number): void
109      */
110     static napi_value JsSetSpeed(napi_env env, napi_callback_info info);
111     /**
112      * setVolume(vol: number): void
113      */
114     static napi_value JsSetVolume(napi_env env, napi_callback_info info);
115     /**
116      * selectBitrate(bitRate: number): void
117      */
118     static napi_value JsSelectBitrate(napi_env env, napi_callback_info info);
119     /**
120      * url: string
121      */
122     static napi_value JsSetUrl(napi_env env, napi_callback_info info);
123     static napi_value JsGetUrl(napi_env env, napi_callback_info info);
124     /**
125      * fdSrc: AVFileDescriptor
126      */
127     static napi_value JsGetAVFileDescriptor(napi_env env, napi_callback_info info);
128     static napi_value JsSetAVFileDescriptor(napi_env env, napi_callback_info info);
129     /**
130      * surfaceId?: string
131      */
132     static napi_value JsSetSurfaceID(napi_env env, napi_callback_info info);
133     static napi_value JsGetSurfaceID(napi_env env, napi_callback_info info);
134     /**
135      * loop: boolenan
136      */
137     static napi_value JsSetLoop(napi_env env, napi_callback_info info);
138     static napi_value JsGetLoop(napi_env env, napi_callback_info info);
139     /**
140      * videoScaleType?: VideoScaleType
141      */
142     static napi_value JsSetVideoScaleType(napi_env env, napi_callback_info info);
143     static napi_value JsGetVideoScaleType(napi_env env, napi_callback_info info);
144     /**
145      * audioInterruptMode?: audio.AudioInterruptMode
146      */
147     static napi_value JsGetAudioInterruptMode(napi_env env, napi_callback_info info);
148     static napi_value JsSetAudioInterruptMode(napi_env env, napi_callback_info info);
149     /**
150      * readonly currentTime: number
151      */
152     static napi_value JsGetCurrentTime(napi_env env, napi_callback_info info);
153     /**
154      * readonly duration: number
155      */
156     static napi_value JsGetDuration(napi_env env, napi_callback_info info);
157     /**
158      * readonly state: AVPlayState
159      */
160     static napi_value JsGetState(napi_env env, napi_callback_info info);
161     /**
162      * readonly width: number
163      */
164     static napi_value JsGetWidth(napi_env env, napi_callback_info info);
165     /**
166      * readonly height: number
167      */
168     static napi_value JsGetHeight(napi_env env, napi_callback_info info);
169     /**
170      * getTrackDescription(callback:AsyncCallback<Array<MediaDescription>>): void
171      * getTrackDescription(): Promise<Array<MediaDescription>>
172      */
173     static napi_value JsGetTrackDescription(napi_env env, napi_callback_info info);
174     /**
175     * on(type: 'stateChange', callback: (state: AVPlayerState, reason: StateChangeReason) => void): void;
176     * off(type: 'stateChange'): void;
177     * on(type: 'volumeChange', callback: Callback<number>): void;
178     * off(type: 'volumeChange'): void;
179     * on(type: 'endOfStream', callback: Callback<void>): void;
180     * off(type: 'endOfStream'): void;
181     * on(type: 'seekDone', callback: Callback<number>): void;
182     * off(type: 'seekDone'): void;
183     * on(type: 'speedDone', callback: Callback<number>): void;
184     * off(type: 'speedDone'): void;
185     * on(type: 'bitrateDone', callback: Callback<number>): void;
186     * off(type: 'bitrateDone'): void;
187     * on(type: 'timeUpdate', callback: Callback<number>): void;
188     * off(type: 'timeUpdate'): void;
189     * on(type: 'durationUpdate', callback: Callback<number>): void;
190     * off(type: 'durationUpdate'): void;
191     * on(type: 'bufferingUpdate', callback: (infoType: BufferingInfoType, value: number) => void): void;
192     * off(type: 'bufferingUpdate'): void;
193     * on(type: 'startRenderFrame', callback: Callback<void>): void;
194     * off(type: 'startRenderFrame'): void;
195     * on(type: 'videoSizeChange', callback: (width: number, height: number) => void): void;
196     * off(type: 'videoSizeChange'): void;
197     * on(type: 'audioInterrupt', callback: (info: audio.InterruptEvent) => void): void;
198     * off(type: 'audioInterrupt'): void;
199     * on(type: 'availableBitrates', callback: (bitrates: Array<number>) => void): void;
200     * off(type: 'availableBitrates'): void;
201     * on(type: 'error', callback: ErrorCallback): void;
202     * off(type: 'error'): void;
203     */
204     static napi_value JsSetOnCallback(napi_env env, napi_callback_info info);
205     static napi_value JsClearOnCallback(napi_env env, napi_callback_info info);
206 
207     static AVPlayerNapi* GetJsInstance(napi_env env, napi_callback_info info);
208     static AVPlayerNapi* GetJsInstanceWithParameter(napi_env env, napi_callback_info info,
209         size_t &argc, napi_value *argv);
210     AVPlayerNapi();
211     ~AVPlayerNapi() override;
212     void SaveCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref);
213     void ClearCallbackReference();
214     void ClearCallbackReference(const std::string &callbackName);
215     void StartListenCurrentResource();
216     void PauseListenCurrentResource();
217     void OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode, const std::string &errorMsg);
218     void SetSource(std::string url);
219     void SetSurface(const std::string &surfaceStr);
220     void ResetUserParameters();
221 
222     std::shared_ptr<TaskHandler<TaskRet>> PrepareTask();
223     std::shared_ptr<TaskHandler<TaskRet>> PlayTask();
224     std::shared_ptr<TaskHandler<TaskRet>> PauseTask();
225     std::shared_ptr<TaskHandler<TaskRet>> StopTask();
226     std::shared_ptr<TaskHandler<TaskRet>> ResetTask();
227     std::shared_ptr<TaskHandler<TaskRet>> ReleaseTask();
228     std::string GetCurrentState();
229     bool IsControllable();
230 
231     void NotifyDuration(int32_t duration) override;
232     void NotifyPosition(int32_t position) override;
233     void NotifyState(PlayerStates state) override;
234     void NotifyVideoSize(int32_t width, int32_t height) override;
235 
236     struct AVPlayerContext : public MediaAsyncContext {
AVPlayerContextAVPlayerContext237         explicit AVPlayerContext(napi_env env) : MediaAsyncContext(env) {}
238         ~AVPlayerContext() = default;
CheckTaskResultAVPlayerContext239         void CheckTaskResult()
240         {
241             if (asyncTask != nullptr) {
242                 auto result = asyncTask->GetResult();
243                 if (result.HasResult() && result.Value().first != MSERR_EXT_API9_OK) {
244                     SignError(result.Value().first, result.Value().second);
245                 }
246             }
247         }
248         std::shared_ptr<TaskHandler<TaskRet>> asyncTask = nullptr;
249         AVPlayerNapi *napi = nullptr;
250     };
251     static thread_local napi_ref constructor_;
252     napi_env env_ = nullptr;
253     std::shared_ptr<Player> player_ = nullptr;
254     std::shared_ptr<AVPlayerCallback> playerCb_ = nullptr;
255     std::atomic<bool> isReleased_ = false;
256     std::string url_ = "";
257     struct AVFileDescriptor fileDescriptor_;
258     std::string surface_ = "";
259     bool loop_ = false;
260     int32_t videoScaleType_ = 0;
261     std::vector<Format> trackInfoVec_;
262     OHOS::AudioStandard::InterruptMode interruptMode_ = AudioStandard::InterruptMode::SHARE_MODE;
263     std::unique_ptr<TaskQueue> taskQue_;
264     std::mutex mutex_;
265     std::mutex taskMutex_;
266     std::map<std::string, std::shared_ptr<AutoRef>> refMap_;
267     PlayerStates state_ = PLAYER_IDLE;
268     std::condition_variable preparingCond_;
269     std::condition_variable stateChangeCond_;
270     std::condition_variable resettingCond_;
271     int32_t width_ = 0;
272     int32_t height_ = 0;
273     int32_t position_ = -1;
274     int32_t duration_ = -1;
275 };
276 } // namespace Media
277 } // namespace OHOS
278 #endif // AV_PLAYER_NAPI_H