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
16/**
17 * @addtogroup UI_Components
18 * @{
19 *
20 * @brief Defines UI components such as buttons, texts, images, lists, and progress bars.
21 *
22 * @since 5.0
23 * @version 3.0
24 */
25
26/**
27 * @file ui_video.h
28 *
29 * @brief Declares the functions related to video playbacks.
30 *
31 * @since 5.0
32 * @version 3.0
33 */
34
35#ifndef GRAPHIC_LITE_UI_VIDEO_H
36#define GRAPHIC_LITE_UI_VIDEO_H
37
38#include "animator/animator.h"
39#include "components/ui_label.h"
40#include "components/ui_slider.h"
41#include "components/ui_surface_view.h"
42#include "components/ui_toggle_button.h"
43#include "components/ui_view_group.h"
44#include "player.h"
45
46#ifndef VERSION_LITE
47namespace OHOS {
48using namespace OHOS::Media;
49/**
50 * @brief Provides the functions related to video playbacks.
51 *
52 * @since 5.0
53 * @version 3.0
54 */
55class UIVideo : public UIViewGroup,
56                public UIView::OnClickListener,
57                public UIView::OnTouchListener,
58                public UISlider::UISliderEventListener {
59public:
60    /**
61     * @brief A constructor used to create a <b>UIVideo</b> instance for playback.
62     *
63     * @since 5.0
64     * @version 3.0
65     */
66    UIVideo();
67
68    /**
69     * @brief A destructor used to delete the <b>UIVideo</b> instance for playback.
70     *
71     * @since 5.0
72     * @version 3.0
73     */
74    virtual ~UIVideo();
75
76    /**
77     * @brief Sets the source file to be played.
78     *
79     * @param source Indicates the pointer to the source file path.
80     * @return Returns <b>true</b> if the setting is successful; returns <b>false</b> otherwise.
81     * @since 5.0
82     * @version 3.0
83     */
84    bool SetSrc(const char* source);
85
86    /**
87     * @brief Obtains the path of the source file to be played.
88     *
89     * @return Returns the path of the source file to be played.
90     * @since 5.0
91     * @version 3.0
92     */
93    const char* GetSrc()
94    {
95        return src_;
96    }
97
98    /**
99     * @brief Prepares for the playback. You must call this function after {@link SetSource}.
100     *
101     * @return Returns <b>true</b> if the preparation is successful; returns <b>false</b> otherwise.
102     * @since 5.0
103     * @version 3.0
104     */
105    bool Prepare();
106
107    /**
108     * @brief Plays this video.
109     *
110     * @return Returns <b>true</b> if this video is played; returns <b>false</b> otherwise.
111     * @since 5.0
112     * @version 3.0
113     */
114    bool Play();
115
116    /**
117     * @brief Checks whether this video is playing.
118     *
119     * @return Returns <b>true</b> if this video is playing; returns <b>false</b> otherwise.
120     * @since 5.0
121     * @version 3.0
122     */
123    bool IsPlaying();
124
125    /**
126     * @brief Pauses the video being played.
127     *
128     * @return Returns <b>true</b> if the video is paused; returns <b>false</b> otherwise.
129     * @since 5.0
130     * @version 3.0
131     */
132    bool Pause();
133
134    /**
135     * @brief Stops playing this video.
136     *
137     * @return Returns <b>true</b> if this video is stopped; returns <b>false</b> otherwise.
138     * @since 5.0
139     * @version 3.0
140     */
141    bool Stop();
142
143    /**
144     * @brief Changes the playback position.
145     *
146     * @param mSeconds Indicates the target playback position, in milliseconds.
147     * @return Returns <b>true</b> if the playback position is changed; returns <b>false</b> otherwise.
148     * @since 5.0
149     * @version 3.0
150     */
151    bool Rewind(int64_t mSeconds);
152
153    /**
154     * @brief Sets the playback volume.
155     *
156     * @param Indicates the volume of the left audio channel to set, ranging from <b>0</b> to <b>100</b>.
157     * @param rightVolume Indicates the volume of the right audio channel to set, ranging from <b>0</b> to <b>1</b>.
158     * @return Returns <b>true</b> if the setting is successful; returns <b>false</b> otherwise.
159     * @since 5.0
160     * @version 3.0
161     */
162    bool SetVolume(float leftVolume, float rightVolume);
163
164    /**
165     * @brief Sets whether to loop playback.
166     *
167     * @param loop Specifies whether to loop playback. The value <b>true</b> means that the playback loops,
168     *             and <b>false</b> means the opposite case.
169     * @return Returns <b>true</b> if the setting is successful; returns <b>false</b> otherwise.
170     * @since 5.0
171     * @version 3.0
172     */
173    bool EnableSingleLooping(bool loop);
174
175    /**
176     * @brief Checks whether the playback loops.
177     *
178     * @return Returns <b> true</b> if the playback loops; returns <b>false</b> otherwise.
179     * @since 5.0
180     * @version 3.0
181     */
182    bool IsSingleLooping();
183
184    /**
185     * @brief Obtains the current playback time.
186     *
187     * @param time Indicates the current playback time, in milliseconds.
188     * @return Returns <b> true</b> if the operation is successful; returns <b>false</b> otherwise.
189     * @since 5.0
190     * @version 3.0
191     */
192    bool GetCurrentTime(int64_t& time);
193
194    /**
195     * @brief Obtains the total video duration.
196     *
197     * @param duration Indicates the total duration, in milliseconds.
198     * @return Returns <b> true</b> if the duration is obtained; returns <b>false</b> otherwise.
199     * @since 5.0
200     * @version 3.0
201     */
202    bool GetDuration(int64_t& duration);
203
204    /**
205     * @brief Resets the player to the initial state.
206     *
207     * @return Returns <b>true</b> if the player is reset; returns <b>false</b> otherwise.
208     * @since 5.0
209     * @version 3.0
210     */
211    bool Reset();
212
213    /**
214     * @brief Sets whether to show the playback controller.
215     *
216     * @param show Specifies whether to show the playback controller. The value <b>true</b> means showing
217     *             the playback controller, and <b>false</b> means the opposite case.
218     * @since 5.0
219     * @version 3.0
220     */
221    void ShowController(bool show);
222
223    /**
224     * @brief Provides callbacks for events that occur during video playback.
225     *
226     * @since 5.0
227     * @version 3.0
228     */
229    class VideoPlayerListener {
230    public:
231        /**
232         * @brief A constructor used to create a <b>VideoPlayerListener</b> instance.
233         *
234         * @since 5.0
235         * @version 3.0
236         */
237        VideoPlayerListener() {}
238
239        /**
240         * @brief A destructor used to delete the <b>VideoPlayerListener</b> instance.
241         *
242         * @since 5.0
243         * @version 3.0
244         */
245        virtual ~VideoPlayerListener() {}
246
247        /**
248         * @brief Called when the playback is complete.
249         *
250         * @since 5.0
251         * @version 3.0
252         */
253        virtual void OnPlaybackComplete() {}
254
255        /**
256         * @brief Called when a video playback error occurs.
257         *
258         * @param errorType Indicates the error type.
259         * @param eerrorCode Indicates the error code.
260         * @since 5.0
261         * @version 3.0
262         */
263        virtual void OnError(int32_t errorType, int32_t errorCode) {}
264
265        /**
266         * @brief Called when playback information is received.
267         *
268         * @param type Indicates the information type.
269         * @param extra Indicates the information code.
270         * @since 5.0
271         * @version 3.0
272         */
273        virtual void OnInfo(int32_t type, int32_t extra) {}
274
275        /**
276         * @brief Called when the video image size changes.
277         *
278         * @param width Indicates the video width.
279         * @param height Indicates the video height.
280         * @since 5.0
281         * @version 3.0
282         */
283        virtual void OnVideoSizeChanged(int32_t width, int32_t height) {}
284
285        /**
286         * @brief Called when this video is rewound.
287         *
288         * @since 5.0
289         * @version 3.0
290         */
291        virtual void OnRewindToComplete() {}
292
293        /**
294         * @brief Called when this video is paused.
295         *
296         * @since 5.0
297         * @version 3.0
298         */
299        virtual void OnPlaybackPause() {}
300
301        /**
302         * @brief Called when this video is played.
303         *
304         * @since 5.0
305         * @version 3.0
306         */
307        virtual void OnPlaybackPlay() {}
308
309        /**
310         * @brief Called when this video is stopped.
311         *
312         * @since 5.0
313         * @version 3.0
314         */
315        virtual void OnPlaybackStop() {}
316    };
317
318    /**
319     * @brief Sets a listener for monitoring video playbacks.
320     *
321     * @param listener Indicates the pointer to the listener to set.
322     * @since 5.0
323     * @version 3.0
324     */
325    void SetVideoPlayerListener(VideoPlayerListener* listener);
326
327private:
328    class SliderAnimatorCallback : public AnimatorCallback {
329    public:
330        SliderAnimatorCallback(UIVideo* video, UISlider* slider, UILabel* label)
331        {
332            video_ = video;
333            slider_ = slider;
334            timeLabel_ = label;
335        }
336
337        virtual ~SliderAnimatorCallback() {}
338        void Callback(UIView* view) override;
339        void SetPlayButton(UIToggleButton* toggleButton)
340        {
341            playButton_ = toggleButton;
342        }
343
344        void SetSliderAnimator(Animator* animator)
345        {
346            sliderAnimator_ = animator;
347        }
348
349        void SetDuration(int64_t duration)
350        {
351            duration_ = duration;
352        }
353
354        void ResetTickTime()
355        {
356            if (sliderAnimator_ != nullptr) {
357                tickCount_ = sliderAnimator_->GetRunTime();
358            }
359        }
360
361        friend class UIVideo;
362    private:
363        uint32_t tickCount_ = 0;
364        int64_t duration_ = 0;
365        UIVideo* video_ = nullptr;
366        UISlider* slider_ = nullptr;
367        UILabel* timeLabel_ = nullptr;
368        UIToggleButton* playButton_ = nullptr;
369        Animator* sliderAnimator_ = nullptr;
370    };
371
372    void InitVideo();
373    void InitControllerLabel();
374    void InitControllerButton();
375    void InitControllerSlider();
376    void DeleteController();
377    void SetSurfaceInfo();
378    void OnVideoComplete();
379    bool GetTimerFromMSecond(int64_t currentTime, char* timer, int32_t len);
380
381    bool OnClick(UIView& view, const ClickEvent& event) override;
382    bool OnPress(UIView& view, const PressEvent& event) override;
383    void OnChange(int32_t progress) override;
384
385    class PlayerListener : public Media::PlayerCallback {
386    public:
387        PlayerListener() {}
388        virtual ~PlayerListener() {}
389        void OnPlaybackComplete() override
390        {
391            if (video_ != nullptr) {
392                video_->OnVideoComplete();
393            }
394            if (videoPlayerListener_ != nullptr) {
395                videoPlayerListener_->OnPlaybackComplete();
396            }
397        }
398
399        void OnError(int32_t errorType, int32_t errorCode) override
400        {
401            if (videoPlayerListener_ != nullptr) {
402                videoPlayerListener_->OnError(errorType, errorCode);
403            }
404        }
405
406        void OnInfo(int32_t type, int32_t extra) override
407        {
408            if (videoPlayerListener_ != nullptr) {
409                videoPlayerListener_->OnInfo(type, extra);
410            }
411        }
412
413        void OnVideoSizeChanged(int32_t width, int32_t height) override
414        {
415            if (videoPlayerListener_ != nullptr) {
416                videoPlayerListener_->OnVideoSizeChanged(width, height);
417            }
418        }
419
420        void OnRewindToComplete() override
421        {
422            if (videoPlayerListener_ != nullptr) {
423                videoPlayerListener_->OnRewindToComplete();
424            }
425        }
426
427        void OnPlaybackPause()
428        {
429            if (videoPlayerListener_ != nullptr) {
430                videoPlayerListener_->OnPlaybackPause();
431            }
432        }
433
434        void OnPlaybackPlay()
435        {
436            if (videoPlayerListener_ != nullptr) {
437                videoPlayerListener_->OnPlaybackPlay();
438            }
439        }
440
441        void OnPlaybackStop()
442        {
443            if (videoPlayerListener_ != nullptr) {
444                videoPlayerListener_->OnPlaybackStop();
445            }
446        }
447
448        void SetVideoPlayer(UIVideo* video)
449        {
450            video_ = video;
451        }
452
453        void SetVideoPlayerListerner(VideoPlayerListener* listener)
454        {
455            videoPlayerListener_ = listener;
456        }
457
458    private:
459        UIVideo* video_ = nullptr;
460        VideoPlayerListener* videoPlayerListener_ = nullptr;
461    };
462
463    bool completeFlag_ = false;
464    float leftVolumeValue_ = DEFAULT_VOLUME;
465    float rightVolumeValue_ = DEFAULT_VOLUME;
466    int64_t duration_ = 0;
467    const char* src_ = nullptr;
468    std::shared_ptr<Player> videoPlayer_ = nullptr;
469    UIViewGroup* controllerGroup_ = nullptr;
470    UILabel* totalTimeLabel_ = nullptr;
471    UILabel* currentTimeLabel_ = nullptr;
472    UILabel* titleLabel_ = nullptr;
473    UISlider* playSlider_ = nullptr;
474    Animator* sliderAnimator_ = nullptr;
475    SliderAnimatorCallback* sliderAnimatorCallback_ = nullptr;
476    UIToggleButton* volumeButton_ = nullptr;
477    UISurfaceView* surfaceView_ = nullptr;
478    UIToggleButton* playButton_ = nullptr;
479    UIToggleButton* pauseButton_ = nullptr;
480    VideoPlayerListener* videoPlayerListener_ = nullptr;
481    std::shared_ptr<PlayerListener> playerListener_ = nullptr;
482
483    static constexpr uint16_t DEFAULT_VIEW_WIDTH = 960;
484    static constexpr uint16_t DEFAULT_VIEW_HEIGHT = 480;
485    static constexpr uint16_t TOGGLE_BUTTON_WIDTH = 32;
486    static constexpr uint16_t TOGGLE_BUTTON_HEIGHT = 32;
487    static constexpr uint16_t TIME_LABEL_WIDTH = 300;
488    static constexpr uint16_t TIME_LABEL_HEIGHT = 20;
489    static constexpr uint16_t KNOB_WIDTH = 18;
490    static constexpr uint16_t FONT_DEFAULT_SIZE = 14;
491    static constexpr uint16_t MAX_VOLUME = 300;
492    static constexpr uint16_t HIDE_MILLI_SECOND = 5000;
493    static constexpr float DEFAULT_VOLUME = 0.5;
494};
495} // namespace OHOS
496
497#endif // VERSION_LITE
498#endif // GRAPHIC_LITE_UI_VIDEO_H
499