diff --git a/DistributedMail/build.gradle b/DistributedMail/build.gradle index bca51e05a07965a3d25dbc382354fb6335224f45..9ec29b00390d8a9ea93959252e81018c673268ba 100644 --- a/DistributedMail/build.gradle +++ b/DistributedMail/build.gradle @@ -2,41 +2,35 @@ apply plugin: 'com.huawei.ohos.app' ohos { - compileSdkVersion 3 + compileSdkVersion 5 defaultConfig { - compatibleSdkVersion 3 + compatibleSdkVersion 4 } } buildscript { repositories { maven { - url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/' + url 'https://repo.huaweicloud.com/repository/maven/' } maven { url 'https://developer.huawei.com/repo/' - } - maven { - url 'http://artifactory.cde.huawei.com/artifactory/Product-Binary-Release' } jcenter() } dependencies { - classpath 'com.huawei.ohos:hap:2.4.1.5' - classpath 'com.huawei.ohos:decctest:1.0.0.+' + classpath 'com.huawei.ohos:hap:2.4.2.7' + classpath 'com.huawei.ohos:decctest:1.0.0.7' } } allprojects { repositories { maven { - url 'https://mirrors.huaweicloud.com/repository/maven/' + url 'https://repo.huaweicloud.com/repository/maven/' } maven { url 'https://developer.huawei.com/repo/' - } - maven { - url 'http://artifactory.cde.huawei.com/artifactory/Product-Binary-Release' } jcenter() } diff --git a/DistributedMail/entry/build.gradle b/DistributedMail/entry/build.gradle index ed02226046851566b832af5925fa9c0f3e4d789c..58332659cff5989dd026ee2aebef6f77e0f833c8 100644 --- a/DistributedMail/entry/build.gradle +++ b/DistributedMail/entry/build.gradle @@ -1,16 +1,16 @@ apply plugin: 'com.huawei.ohos.hap' apply plugin: 'com.huawei.ohos.decctest' ohos { - compileSdkVersion 3 + compileSdkVersion 5 defaultConfig { - compatibleSdkVersion 3 + compatibleSdkVersion 4 } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - testCompile 'junit:junit:4.12' - ohosTestImplementation 'decc.testkit:harmonyjunitrunner:0.3' + testCompile 'junit:junit:4.13' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100' } decc { supportType = ['html', 'xml'] diff --git a/DistributedMail/entry/src/main/config.json b/DistributedMail/entry/src/main/config.json index b0d3a3ce8b6c2979e8725d44a7d91361e73a1bc9..70f58af9d3cbfd99ac134f0a6c130cbec0c24760 100644 --- a/DistributedMail/entry/src/main/config.json +++ b/DistributedMail/entry/src/main/config.json @@ -7,8 +7,8 @@ "name": "1.0" }, "apiVersion": { - "compatible": 3, - "target": 3 + "compatible": 4, + "target": 5 } }, "deviceConfig": {}, diff --git a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/big.png b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/big.png index 2a3c36c76c86db73f10c41b2e7fdfa98d648604d..42698673f33b16921ce89deea7a3bea162ad6893 100644 Binary files a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/big.png and b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/big.png differ diff --git a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/boom.png b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/boom.png index 7fa70036c1affaa2207b82c65da40e015886d70c..33249b8f84b0c1f5720b04c39fa9e8b3f335238b 100644 Binary files a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/boom.png and b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/boom.png differ diff --git a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/planeOne.png b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/planeOne.png index 57e82f4fea1ccce9c3afa824afcc1fc0ddd314d2..e601283d8f7502bfd92e540674d1bfdd712e4b63 100644 Binary files a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/planeOne.png and b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/planeOne.png differ diff --git a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/planeTwo.png b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/planeTwo.png index c765b14fd3dd6ecbb321e64702371e52fbc263db..8c3e52e05de692af225e756a52e9b4fdee7e1144 100644 Binary files a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/planeTwo.png and b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/planeTwo.png differ diff --git a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/small.png b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/small.png index 85578dbaee76bf4d3af624d730b0416e6d509fa7..42698673f33b16921ce89deea7a3bea162ad6893 100644 Binary files a/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/small.png and b/DistributionGamePad-master/GameApplication/entry/src/main/resources/base/media/small.png differ diff --git a/HarmonyOSNewsClient/entry/src/main/java/com/huawei/codelab/SharedService.java b/HarmonyOSNewsClient/entry/src/main/java/com/huawei/codelab/SharedService.java index b2749be2835607e32ffb141b3fd87c13d4adcbb6..92bdef9a90147bf143953ea0cd8d762552dd16e6 100644 --- a/HarmonyOSNewsClient/entry/src/main/java/com/huawei/codelab/SharedService.java +++ b/HarmonyOSNewsClient/entry/src/main/java/com/huawei/codelab/SharedService.java @@ -29,7 +29,7 @@ import ohos.rpc.IRemoteObject; * @since 2020-12-04 */ public class SharedService extends Ability { - private static final String DESCRIPTOR = "com.huawei.codelab.idl.ITencentNewsAIDL"; + private static final String DESCRIPTOR = "com.huawei.codelab.INewsDemoIDL"; @Override protected void onStart(Intent intent) { diff --git a/README.md b/README.md index ef45ed83718f118c37529538932034006117f642..8374a204a9ecc2ac46899a4cc6eda5b4392d104b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,6 @@ VoiceCamera:展示了一个基于分布式文件系统和AI语音识别功能 JSPlaygroundDemo:利用HarmonyOS“一次开发、多端部署”特性,开发一个能同时运行在手机、大屏、运动表的“To-Do List”Demo,链接:https://gitee.com/openharmony/codelabs/tree/master/JSPlaygroundDemo -RemoteInputDemo:展示了通过手机输入文字到电视的跨设备输入能力,链接:https://gitee.com/h00358227/codelabs/tree/master/RemoteInputDemo-master +RemoteInputDemo:展示了通过手机输入文字到电视的跨设备输入能力,链接:https://gitee.com/openharmony/codelabs/tree/master/RemoteInputDemo-master -DistributionGamePad:分布式游戏手柄,可以通过手机端跨设备控制电视上的飞机游戏,链接:https://gitee.com/h00358227/codelabs/tree/master/DistributionGamePad-master \ No newline at end of file +DistributionGamePad:分布式游戏手柄,可以通过手机端跨设备控制电视上的飞机游戏,链接:https://gitee.com/openharmony/codelabs/tree/master/DistributionGamePad-master diff --git a/SimpleVideoCodelab/entry/src/main/config.json b/SimpleVideoCodelab/entry/src/main/config.json index e069a1bc15a71321e2645ab8b0cff43334979a7c..7129c990c78bb56b5463cd2b69f498a334ce7acd 100644 --- a/SimpleVideoCodelab/entry/src/main/config.json +++ b/SimpleVideoCodelab/entry/src/main/config.json @@ -38,7 +38,10 @@ ] } ], - "orientation": "portrait", + "orientation": "unspecified", + "configChanges": [ + "orientation" + ], "formEnabled": false, "name": "com.huawei.codelab.MainAbility", "icon": "$media:icon", diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/MainAbility.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/MainAbility.java index 5394942455e99896066972d7374d90b441ae2b5c..7beede00789c2747b217e77ac65d918d973e682b 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/MainAbility.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/MainAbility.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,14 @@ package com.huawei.codelab; import com.huawei.codelab.slice.SimplePlayerAbilitySlice; + import ohos.aafwk.ability.Ability; import ohos.aafwk.content.Intent; /** * the main page * - * @since 2020-12-04 + * @since 2021-04-04 * */ public class MainAbility extends Ability { diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/HmPlayer.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/HmPlayer.java index 10e2267260df7f25fa50c1d83fb7de78631e0895..6fd3e96c71bf0f0426e3c4111be56eb9c4e2a39e 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/HmPlayer.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/HmPlayer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,83 +16,44 @@ package com.huawei.codelab.player; -import com.huawei.codelab.player.constant.PlayerStatus; -import com.huawei.codelab.player.factory.SourceFactory; -import com.huawei.codelab.player.manager.HmPlayerLifecycle; -import com.huawei.codelab.util.LogUtil; import com.huawei.codelab.player.api.ImplLifecycle; import com.huawei.codelab.player.api.ImplPlayer; import com.huawei.codelab.player.api.ScreenChangeListener; -import com.huawei.codelab.player.api.StatusChangeListener; -import com.huawei.codelab.util.DateUtils; +import com.huawei.codelab.player.api.StatuChangeListener; +import com.huawei.codelab.player.constant.Constants; +import com.huawei.codelab.player.constant.PlayerStatu; +import com.huawei.codelab.player.factory.SourceFactory; +import com.huawei.codelab.player.manager.HmPlayerLifecycle; +import com.huawei.codelab.util.LogUtil; -import ohos.agp.components.Component; -import ohos.agp.components.DependentLayout; -import ohos.agp.components.surfaceprovider.SurfaceProvider; import ohos.agp.graphics.Surface; -import ohos.agp.graphics.SurfaceOps; -import ohos.agp.window.service.WindowManager; import ohos.app.Context; -import ohos.media.audio.AudioManager; -import ohos.media.audio.AudioRemoteException; +import ohos.app.dispatcher.task.TaskPriority; import ohos.media.common.Source; import ohos.media.player.Player; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; /** * Hm player * - * @since 2020-12-04 + * @since 2021-04-04 */ public class HmPlayer implements ImplPlayer { - private static final String TAG = "HmPlayer"; + private static final String TAG = HmPlayer.class.getSimpleName(); private static final int MICRO_MILLI_RATE = 1000; - private static final int MAX_MUSIC_VOLUME = 100; - private static final int MIM_MUSIC_VOLUME = 0; - private static final int CAPACITY = 6; - private static final int CORE_POOL_SIZE = 2; - private static final int MAX_POOL_SIZE = 20; - private static final int KEEP_ALIVE_TIME = 3; - private Player player; - private SurfaceProvider surfaceView; + private Player mPlayer; private Surface surface; - private AudioManager audio; - private HmPlayerLifecycle lifecycle; - private Builder playerBuilder; - private PlayerStatus status = PlayerStatus.IDEL; - - private List statusChangeCallbacks = new ArrayList<>(0); + private HmPlayerLifecycle mLifecycle; + private Builder mBuilder; + private PlayerStatu mStatu = PlayerStatu.IDEL; + private float currentVolume = 1; + private double videoScale = Constants.NUMBER_NEGATIVE_1; + private boolean isGestureOpen; + + private List statuChangeCallbacks = new ArrayList<>(0); private List screenChangeCallbacks = new ArrayList<>(0); - private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, - KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<>(CAPACITY), - new ThreadPoolExecutor.DiscardOldestPolicy()); - private boolean isSurfaceViewCreated; - - private SurfaceOps.Callback surfaceCallback = new SurfaceOps.Callback() { - @Override - public void surfaceCreated(SurfaceOps surfaceOps) { - LogUtil.info(TAG, "surfaceCreated"); - isSurfaceViewCreated = true; - surface = surfaceOps.getSurface(); - start(); - } - - @Override - public void surfaceChanged(SurfaceOps surfaceOps, int i, int width, int height) { - LogUtil.info(TAG, "surfaceChanged i is " + i + ",width is " + width + ",height is " + height); - } - - @Override - public void surfaceDestroyed(SurfaceOps surfaceOps) { - LogUtil.info(TAG, "surfaceDestroyed"); - isSurfaceViewCreated = false; - } - }; /** * constructor of HmPlayer @@ -100,20 +61,15 @@ public class HmPlayer implements ImplPlayer { * @param builder builder */ private HmPlayer(Builder builder) { - playerBuilder = builder; - WindowManager.getInstance().getTopWindow().get().setTransparent(true); // 不设置窗体透明会挡住播放内容,除非设置pinToZTop为true - audio = new AudioManager(playerBuilder.context.getBundleName()); - lifecycle = new HmPlayerLifecycle(this); - surfaceView = new SurfaceProvider(playerBuilder.context); - DependentLayout.LayoutConfig layoutConfig = new DependentLayout.LayoutConfig(); - layoutConfig.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT); - surfaceView.setLayoutConfig(layoutConfig); - surfaceView.setVisibility(Component.VISIBLE); - surfaceView.setFocusable(Component.FOCUS_ENABLE); - surfaceView.setTouchFocusable(true); - surfaceView.requestFocus(); - surfaceView.pinToZTop(playerBuilder.isTopPlay); - surfaceView.getSurfaceOps().get().addCallback(surfaceCallback); + mBuilder = builder; + mLifecycle = new HmPlayerLifecycle(this); + } + + private void initBasePlayer() { + mPlayer = new Player(mBuilder.mContext); + Source source = new SourceFactory(mBuilder.mContext, mBuilder.filePath).getSource(); + mPlayer.setSource(source); + mPlayer.setPlayerCallback(new HmPlayerCallback()); } /** @@ -125,85 +81,77 @@ public class HmPlayer implements ImplPlayer { @Override public void onPrepared() { LogUtil.info(TAG, "onPrepared is called "); - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.PREPARED; - callback.statusCallback(PlayerStatus.PREPARED); + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.PREPARED; + callback.statuCallback(PlayerStatu.PREPARED); } } @Override public void onMessage(int info, int i1) { LogUtil.info(TAG, "onMessage info is " + info + ",i1 is" + i1); - if (info == Player.PLAYER_INFO_VIDEO_RENDERING_START && i1 == 0) { - // start to rendering ,show controller - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.PLAY; - callback.statusCallback(PlayerStatus.PLAY); - } - } else if (info == Player.PLAYER_INFO_BUFFERING_START && i1 == 0) { - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.BUFFERING; - callback.statusCallback(PlayerStatus.BUFFERING); - } - } else if (info == Player.PLAYER_INFO_BUFFERING_END && i1 == 0) { - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.PLAY; - callback.statusCallback(PlayerStatus.PLAY); + if (i1 == 0) { + switch (info) { + case Player.PLAYER_INFO_VIDEO_RENDERING_START: + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.PLAY; + callback.statuCallback(PlayerStatu.PLAY); + } + if (mBuilder.isPause) { + pause(); + } + break; + case Player.PLAYER_INFO_BUFFERING_START: + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.BUFFERING; + callback.statuCallback(PlayerStatu.BUFFERING); + } + break; + case Player.PLAYER_INFO_BUFFERING_END: + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.PLAY; + callback.statuCallback(PlayerStatu.PLAY); + } + break; + default: + break; } - } else { - LogUtil.info(TAG, "onMessage else message"); } } @Override - public void onError(int i, int i1) { - LogUtil.info(TAG, "onError is called ,i is " + i + ",i1 is " + i1); - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.ERROR; - callback.statusCallback(PlayerStatus.ERROR); + public void onError(int type, int extra) { + LogUtil.info(TAG, "onError is called ,i is " + type + ",i1 is " + extra); + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.ERROR; + callback.statuCallback(PlayerStatu.ERROR); } release(); } @Override - public void onResolutionChanged(int x, int y) { - LogUtil.info(TAG, "onResolutionChanged i is " + x + ",i1 is " + y); - if (!playerBuilder.isStretch && x != 0 && y != 0) { - getBuilder().context.getUITaskDispatcher().delayDispatch(new Runnable() { - @Override - public void run() { - if (x > y) { - surfaceView.setWidth(surfaceView.getWidth()); - surfaceView.setHeight(Math.min(y * surfaceView.getWidth() / x, surfaceView.getHeight())); - } else { - surfaceView.setHeight(surfaceView.getHeight()); - surfaceView.setWidth(Math.min(x * surfaceView.getHeight() / y, surfaceView.getWidth())); - } - } - }, 0); + public void onResolutionChanged(int videoX, int videoY) { + LogUtil.info(TAG, "onResolutionChanged videoX is " + videoX + ",videoY is " + videoY); + if (!mBuilder.isStretch && videoX != 0 && videoY != 0) { + videoScale = (double) videoX / videoY; } } @Override public void onPlayBackComplete() { - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.COMPLETE; - callback.statusCallback(PlayerStatus.COMPLETE); + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.COMPLETE; + callback.statuCallback(PlayerStatu.COMPLETE); } - stop(); } @Override public void onRewindToComplete() { resume(); - if (playerBuilder.isPause) { - playerBuilder.isPause = false; - pause(); - } } @Override - public void onBufferingChange(int i) { + public void onBufferingChange(int value) { } @Override @@ -214,6 +162,18 @@ public class HmPlayer implements ImplPlayer { @Override public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) { LogUtil.info(TAG, "onMediaTimeIncontinuity is called"); + for (Player.StreamInfo streanInfo : mPlayer.getStreamInfo()) { + int streamType = streanInfo.getStreamType(); + if (streamType == Player.StreamInfo.MEDIA_STREAM_TYPE_AUDIO && mStatu == PlayerStatu.PREPARED) { + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.PLAY; + callback.statuCallback(PlayerStatu.PLAY); + } + if (mBuilder.isPause) { + pause(); + } + } + } } } @@ -221,40 +181,43 @@ public class HmPlayer implements ImplPlayer { * start time consuming operation */ private void start() { - if (isSurfaceViewCreated) { - threadPoolExecutor.execute(() -> { - player.setVideoSurface(surface); - player.prepare(); - if (playerBuilder.startMillisecond > 0) { - int microsecond = playerBuilder.startMillisecond * MICRO_MILLI_RATE; - player.rewindTo(microsecond); + if (mPlayer != null) { + mBuilder.mContext.getGlobalTaskDispatcher(TaskPriority.DEFAULT).asyncDispatch(() -> { + if (surface != null) { + mPlayer.setVideoSurface(surface); } else { - player.play(); + LogUtil.error(TAG, "The surface has not been initialized."); } + mPlayer.prepare(); + if (mBuilder.startMillisecond > 0) { + int microsecond = mBuilder.startMillisecond * MICRO_MILLI_RATE; + mPlayer.rewindTo(microsecond); + } + mPlayer.play(); }); } } @Override - public SurfaceProvider getPlayerView() { - return surfaceView; + public ImplLifecycle getLifecycle() { + return mLifecycle; } @Override - public ImplLifecycle getLifecycle() { - return lifecycle; + public void addSurface(Surface videoSurface) { + this.surface = videoSurface; } @Override - public void addPlayerStatusCallback(StatusChangeListener callback) { + public void addPlayerStatuCallback(StatuChangeListener callback) { if (callback != null) { - statusChangeCallbacks.add(callback); + statuChangeCallbacks.add(callback); } } @Override - public void removePlayerStatuCallback(StatusChangeListener callback) { - statusChangeCallbacks.remove(callback); + public void removePlayerStatuCallback(StatuChangeListener callback) { + statuChangeCallbacks.remove(callback); } @Override @@ -271,25 +234,41 @@ public class HmPlayer implements ImplPlayer { @Override public Builder getBuilder() { - return playerBuilder; + return mBuilder; + } + + @Override + public PlayerStatu getPlayerStatu() { + return mStatu; + } + + @Override + public void resizeScreen(int width, int height) { + for (ScreenChangeListener screenChangeCallback : screenChangeCallbacks) { + screenChangeCallback.screenCallback(width, height); + } } @Override - public PlayerStatus getPlayerStatu() { - return status; + public void openGesture(boolean isOpen) { + isGestureOpen = isOpen; + } + + @Override + public boolean isGestureOpen() { + return isPlaying() && isGestureOpen; } @Override public void play() { - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.PREPARING; - callback.statusCallback(PlayerStatus.PREPARING); - } - release(); - player = new Player(playerBuilder.context); - player.setPlayerCallback(new HmPlayerCallback()); - Source source = new SourceFactory(playerBuilder.context, playerBuilder.filePath).getSource(); - player.setSource(source); + if (mPlayer != null) { + mPlayer.reset(); + } + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.PREPARING; + callback.statuCallback(PlayerStatu.PREPARING); + } + initBasePlayer(); start(); } @@ -298,201 +277,150 @@ public class HmPlayer implements ImplPlayer { if (isPlaying()) { rewindTo(0); } else { - reload(playerBuilder.filePath, 0); + reload(mBuilder.filePath, 0); } } @Override public void reload(String filepath, int startMillisecond) { - playerBuilder.filePath = filepath; - playerBuilder.startMillisecond = startMillisecond; + mBuilder.filePath = filepath; + mBuilder.startMillisecond = startMillisecond; play(); } @Override public void stop() { - if (player == null) { + if (mPlayer == null) { return; } - player.stop(); - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.STOP; - callback.statusCallback(PlayerStatus.STOP); + mPlayer.stop(); + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.STOP; + callback.statuCallback(PlayerStatu.STOP); } } @Override public void release() { - if (player == null) { + if (mPlayer == null) { return; } - if (status != PlayerStatus.IDEL) { - player.release(); - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.IDEL; - callback.statusCallback(PlayerStatus.IDEL); + if (mStatu != PlayerStatu.IDEL) { + videoScale = Constants.NUMBER_NEGATIVE_1; + mPlayer.release(); + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.IDEL; + callback.statuCallback(PlayerStatu.IDEL); } } } - /** - * resume playback - */ @Override public void resume() { - if (player == null) { + if (mPlayer == null) { return; } - if (status != PlayerStatus.IDEL) { + if (mStatu != PlayerStatu.IDEL) { if (!isPlaying()) { - player.play(); + mPlayer.play(); } - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.PLAY; - callback.statusCallback(PlayerStatus.PLAY); + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.PLAY; + callback.statuCallback(PlayerStatu.PLAY); } } } - /** - * pause playback - */ @Override public void pause() { - if (player == null) { + if (mPlayer == null) { return; } if (isPlaying()) { - player.pause(); - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.PAUSE; - callback.statusCallback(PlayerStatus.PAUSE); + mPlayer.pause(); + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.PAUSE; + callback.statuCallback(PlayerStatu.PAUSE); } } } - /** - * Get audio current play position - * - * @return play position - */ @Override - public int getAudioCurrentPosition() { - if (player == null) { + public int getCurrentPosition() { + if (mPlayer == null) { return 0; } - return player.getCurrentTime(); + return mPlayer.getCurrentTime(); } - /** - * Get audio duration - * - * @return audio duration - */ @Override - public int getAudioDuration() { - if (player == null) { + public int getDuration() { + if (mPlayer == null) { return 0; } - return player.getDuration(); + return mPlayer.getDuration(); } @Override - public int getVolume() { - int curVolume = 0; - if (audio == null) { - return curVolume; - } - try { - curVolume = audio.getVolume(AudioManager.AudioVolumeType.STREAM_MUSIC); - } catch (AudioRemoteException e) { - LogUtil.error(TAG, "get current volume failed"); - } - return curVolume; + public float getVolume() { + return currentVolume; } @Override - public void setVolume(int volume) { - if (audio == null) { - return; - } - if (volume > MAX_MUSIC_VOLUME) { - audio.setVolume(AudioManager.AudioVolumeType.STREAM_MUSIC, MAX_MUSIC_VOLUME); - } else if (volume < MIM_MUSIC_VOLUME) { - audio.setVolume(AudioManager.AudioVolumeType.STREAM_MUSIC, MIM_MUSIC_VOLUME); - } else { - audio.setVolume(AudioManager.AudioVolumeType.STREAM_MUSIC, volume); + public void setVolume(float volume) { + if (mPlayer != null) { + if (mPlayer.setVolume(volume)) { + currentVolume = volume; + } } } - /** - * set play speed - * - * @param speed 0~12 - */ @Override public void setPlaySpeed(float speed) { - if (player == null) { + if (mPlayer == null) { return; } - if (status != PlayerStatus.IDEL) { - player.setPlaybackSpeed(speed); + if (mStatu != PlayerStatu.IDEL) { + mPlayer.setPlaybackSpeed(speed); } } @Override - public void changeScreen() { + public double getVideoScale() { + return videoScale; } - /** - * whether player is running or not - * - * @return isPlaying boolean - */ @Override public boolean isPlaying() { - return player.isNowPlaying(); + if (mPlayer != null) { + return mPlayer.isNowPlaying(); + } + return false; } - /** - * Rewind to specified time position - * - * @param startMicrosecond time - */ @Override public void rewindTo(int startMicrosecond) { - if (player == null) { + if (mPlayer == null) { return; } - if (status != PlayerStatus.IDEL) { - for (StatusChangeListener callback : statusChangeCallbacks) { - status = PlayerStatus.BUFFERING; - callback.statusCallback(PlayerStatus.BUFFERING); + if (mStatu != PlayerStatu.IDEL) { + for (StatuChangeListener callback : statuChangeCallbacks) { + mStatu = PlayerStatu.BUFFERING; + callback.statuCallback(PlayerStatu.BUFFERING); } - player.rewindTo(startMicrosecond * MICRO_MILLI_RATE); + mPlayer.rewindTo(startMicrosecond * MICRO_MILLI_RATE); } } - @Override - public String getDurationText() { - return DateUtils.msToString(getAudioDuration()); - } - - @Override - public String getCurrentText() { - return DateUtils.msToString(getAudioCurrentPosition()); - } - /** * Builder * * @since 2020-12-04 */ public static class Builder { - private Context context; - private String filePath = ""; - private int startMillisecond = 0; - private boolean isTopPlay; + private Context mContext; + private String filePath; + private int startMillisecond; private boolean isStretch; private boolean isPause; @@ -502,7 +430,9 @@ public class HmPlayer implements ImplPlayer { * @param context context */ public Builder(Context context) { - this.context = context; + mContext = context; + filePath = ""; + startMillisecond = 0; } /** @@ -545,43 +475,32 @@ public class HmPlayer implements ImplPlayer { return startMillisecond; } - /** - * setTopPlay of Builder - * - * @param topPlay topPlay - * @return Builder - */ - public Builder setTopPlay(boolean topPlay) { - isTopPlay = topPlay; - return this; - } - /** * setStretch of Builder * - * @param stretch stretch + * @param isS isStretch * @return Builder */ - public Builder setStretch(boolean stretch) { - isStretch = stretch; + public Builder setStretch(boolean isS) { + this.isStretch = isS; return this; } /** * setPause of Builder * - * @param pause pause + * @param isP isPause * @return Builder */ - public Builder setPause(boolean pause) { - isPause = pause; + public Builder setPause(boolean isP) { + this.isPause = isP; return this; } /** - * create of ImplPlayer + * create of Builder * - * @return ImplPlayer + * @return IPlayer */ public ImplPlayer create() { return new HmPlayer(this); diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplLifecycle.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplLifecycle.java index bb71f199c610e012efbd2e2556c6c443ba46e345..b9229f4722633e21ba8fd61a8635be0e4a490178 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplLifecycle.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplLifecycle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,30 +19,30 @@ package com.huawei.codelab.player.api; /** * ImplLifecycle * - * @since 2020-12-04 + * @since 2021-04-09 + * */ - public interface ImplLifecycle { /** - * start the HmPlayer + * onStart * */ void onStart(); /** - * turn the HmPlayer foreground + * onForeground * */ void onForeground(); /** - * turn the HmPlayer to background + * onBackground * */ void onBackground(); /** - * stop the HmPlayer + * onStop * */ void onStop(); diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplPlayModule.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplPlayModule.java new file mode 100644 index 0000000000000000000000000000000000000000..f647ba9dedcf33df483d97d933cf277e26da1957 --- /dev/null +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplPlayModule.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.huawei.codelab.player.api; + +/** + * IPlayModuler + * + * @since 2021-04-09 + * + */ +public interface ImplPlayModule { + /** + * bind + * + * @param player player + */ + void bind(ImplPlayer player); + + /** + * unbind + * + */ + void unbind(); +} diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplPlayer.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplPlayer.java index 7aca063e7504dca3fd367a65f1f4e51992686889..9ee31bc3e002bb02eda957da6ed7e27080da48c0 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplPlayer.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ImplPlayer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,54 +17,58 @@ package com.huawei.codelab.player.api; import com.huawei.codelab.player.HmPlayer; -import com.huawei.codelab.player.constant.PlayerStatus; +import com.huawei.codelab.player.constant.PlayerStatu; -import ohos.agp.components.surfaceprovider.SurfaceProvider; +import ohos.agp.graphics.Surface; /** * IPlayer interface * - * @since 2020-12-04 - * + * @since 2021-04-04 */ public interface ImplPlayer { /** - * Player + * addSurface + * + * @param surface surface + */ + void addSurface(Surface surface); + + /** + * addPlayerStatuCallback * * @param callback callback */ - void addPlayerStatusCallback(StatusChangeListener callback); + void addPlayerStatuCallback(StatuChangeListener callback); /** - * Player + * removePlayerStatuCallback * * @param callback callback */ - void removePlayerStatuCallback(StatusChangeListener callback); + void removePlayerStatuCallback(StatuChangeListener callback); /** - * Player + * addPlayerViewCallback * * @param callback callback */ void addPlayerViewCallback(ScreenChangeListener callback); /** - * Player + * removePlayerViewCallback * * @param callback callback */ void removePlayerViewCallback(ScreenChangeListener callback); /** - * play the video - * + * play */ void play(); /** * replay - * */ void replay(); @@ -78,104 +82,80 @@ public interface ImplPlayer { /** * resume - * */ void resume(); /** * pause - * */ void pause(); /** - * getAudioCurrentPosition + * getCurrentPosition * - * @return int + * @return current position */ - int getAudioCurrentPosition(); + int getCurrentPosition(); /** - * getAudioDuration + * getDuration * - * @return int + * @return duration */ - int getAudioDuration(); - - /** - * getDurationText - * - * @return string - */ - String getDurationText(); - - /** - * getCurrentText - * - * @return string - */ - String getCurrentText(); + int getDuration(); /** * getVolume * - * @return int + * @return float */ - int getVolume(); + float getVolume(); /** - * setVolume + * set play volume * - * @param volume volume + * @param volume 0~1 */ - void setVolume(int volume); + void setVolume(float volume); /** - * setPlaySpeed + * set play speed * - * @param speed speed + * @param speed 0~12 */ void setPlaySpeed(float speed); /** - * change the screen direction + * getVideoScale * + * @return double */ - void changeScreen(); + double getVideoScale(); /** * rewindTo * - * @param startMicrosecond startMicrosecond + * @param startMicrosecond startMicrosecond(ms) */ void rewindTo(int startMicrosecond); /** * isPlaying * - * @return true + * @return isPlaying */ boolean isPlaying(); /** - * stop the video - * + * stop */ void stop(); /** - * release the video - * + * release */ void release(); - /** - * getPlayerView - * - * @return SurfaceProvider - */ - SurfaceProvider getPlayerView(); - /** * getLifecycle * @@ -193,7 +173,29 @@ public interface ImplPlayer { /** * getPlayerStatu * - * @return PlayerStatus + * @return PlayerStatu + */ + PlayerStatu getPlayerStatu(); + + /** + * resizeScreen + * + * @param width width + * @param height height + */ + void resizeScreen(int width, int height); + + /** + * openGesture + * + * @param isOpen isOpen + */ + void openGesture(boolean isOpen); + + /** + * openGesture + * + * @return isGestureOpen */ - PlayerStatus getPlayerStatu(); + boolean isGestureOpen(); } diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ScreenChangeListener.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ScreenChangeListener.java index 8832f8a1d1e9d7bb1eae266e8475cde6ac791476..2081c98ce203bc8f35e6476ead5e2f082d0d2f26 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ScreenChangeListener.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/ScreenChangeListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ package com.huawei.codelab.player.api; /** * ScreenChangeListener interface * - * @since 2020-12-04 + * @since 2021-04-04 * */ public interface ScreenChangeListener { diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/StatusChangeListener.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/StatuChangeListener.java similarity index 69% rename from SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/StatusChangeListener.java rename to SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/StatuChangeListener.java index 670ee6633e9066682a9f80a65190d3ab800dc325..3032bf44d2999b395375ec43babb73887457f797 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/StatusChangeListener.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/api/StatuChangeListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,19 +16,19 @@ package com.huawei.codelab.player.api; -import com.huawei.codelab.player.constant.PlayerStatus; +import com.huawei.codelab.player.constant.PlayerStatu; /** - * StatusChangeListener interface + * StatuChangeListener interface * - * @since 2020-12-04 + * @since 2021-04-04 * */ -public interface StatusChangeListener { +public interface StatuChangeListener { /** * statuCallback * - * @param status status + * @param statu statu */ - void statusCallback(PlayerStatus status); + void statuCallback(PlayerStatu statu); } diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/Constants.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/Constants.java index 503938d218672958baf91ba4a12986fd78867a41..2c581152b415b47db6caba2c214cb81dbe2c9962 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/Constants.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,37 +19,75 @@ package com.huawei.codelab.player.constant; /** * Constants * - * @since 2020-12-04 + * @since 2021-04-04 */ public class Constants { + /** + * -1 + */ + public static final int NUMBER_NEGATIVE_1 = -1; + /** + * 2 + */ + public static final int NUMBER_2 = 2; + /** + * 2.0 + */ + public static final float NUMBER_FLOAT_2 = 2f; + /** + * 10 + */ + public static final int NUMBER_10 = 10; + /** + * 25 + */ + public static final int NUMBER_25 = 25; + /** + * 36 + */ + public static final int NUMBER_36 = 36; + /** + * 40 + */ + public static final int NUMBER_40 = 40; + /** + * 100 + */ + public static final int NUMBER_100 = 100; + /** + * 300 + */ + public static final int NUMBER_300 = 300; + /** + * 150 + */ + public static final int NUMBER_150 = 150; + /** + * 1000 + */ + public static final int NUMBER_1000 = 1000; /** * running - * */ public static final int PLAYER_PROGRESS_RUNNING = 0; /** - * controller hide - * + * hide */ public static final int PLAYER_CONTROLLER_HIDE = 1; /** - * controller show - * + * hide */ public static final int PLAYER_CONTROLLER_SHOW = 2; /** * 100 - * */ public static final int ONE_HUNDRED_PERCENT = 100; /** * rewind step - * */ public static final int REWIND_STEP = 5000; /** * volume step - * */ public static final int VOLUME_STEP = 5; /** @@ -64,6 +102,10 @@ public class Constants { * INTENT PLAYSTATU PARAM */ public static final String INTENT_PLAYSTATU_PARAM = "intetn_playstatu_param"; + /** + * INTENT LANDSCREEN REQUEST CODE + */ + public static final int INTENT_LANDSCREEN_REQUEST_CODE = 1001; private Constants() { } diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/GestureConst.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/GestureConst.java new file mode 100644 index 0000000000000000000000000000000000000000..d13417eba417a7dd30b2886f4e4e7fa370330469 --- /dev/null +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/GestureConst.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + */ + +package com.huawei.codelab.player.constant; + +/** + * GestureConst + * + * @since 2021-04-04 + */ +public class GestureConst { + private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500; + + private static final int TOUCH_SLOP = 64; + + private static final int TAP_TIMEOUT = 100; + + private static final int DOUBLE_TAP_TIMEOUT = 300; + + private static final int DOUBLE_TAP_MIN_TIME = 40; + + private static final int DOUBLE_TAP_SLOP = 100; + + private static final int MINIMUM_FLING_VELOCITY = 50; + + private static final int MAXIMUM_FLING_VELOCITY = 8000; + + private static final int DOUBLE_TAP_TOUCH_SLOP = TOUCH_SLOP; + + private static final float AMBIGUOUS_GESTURE_MULTIPLIER = 2f; + + private GestureConst() { + } + + /** + * getDoubleTapTimeout + * + * @return int + */ + public static int getDoubleTapTimeout() { + return DOUBLE_TAP_TIMEOUT; + } + + /** + * getDoubleTapMinTime + * + * @return int + */ + public static int getDoubleTapMinTime() { + return DOUBLE_TAP_MIN_TIME; + } + + /** + * getTouchSlop + * + * @return int + */ + public static int getTouchSlop() { + return TOUCH_SLOP; + } + + /** + * getLongPressTimeout + * + * @return int + */ + public static int getLongPressTimeout() { + return DEFAULT_LONG_PRESS_TIMEOUT; + } + + /** + * getTapTimeout + * + * @return int + */ + public static int getTapTimeout() { + return TAP_TIMEOUT; + } + + /** + * getDoubleTapSlop + * + * @return int + */ + public static int getDoubleTapSlop() { + return DOUBLE_TAP_SLOP; + } + + /** + * getMinimumFlingVelocity + * + * @return int + */ + public static int getMinimumFlingVelocity() { + return MINIMUM_FLING_VELOCITY; + } + + /** + * getMaximumFlingVelocity + * + * @return int + */ + public static int getMaximumFlingVelocity() { + return MAXIMUM_FLING_VELOCITY; + } + + /** + * getScaledTouchSlop + * + * @return int + */ + public static int getScaledTouchSlop() { + return TOUCH_SLOP; + } + + /** + * getScaledDoubleTapTouchSlop + * + * @return int + */ + public static int getScaledDoubleTapTouchSlop() { + return DOUBLE_TAP_TOUCH_SLOP; + } + + /** + * getScaledDoubleTapSlop + * + * @return int + */ + public static int getScaledDoubleTapSlop() { + return DOUBLE_TAP_SLOP; + } + + /** + * getScaledMinimumFlingVelocity + * + * @return int + */ + public static int getScaledMinimumFlingVelocity() { + return MINIMUM_FLING_VELOCITY; + } + + /** + * getScaledMaximumFlingVelocity + * + * @return int + */ + public static int getScaledMaximumFlingVelocity() { + return MAXIMUM_FLING_VELOCITY; + } + + /** + * getAmbiguousGestureMultiplier + * + * @return int + */ + public static float getAmbiguousGestureMultiplier() { + return AMBIGUOUS_GESTURE_MULTIPLIER; + } +} diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/PlayerStatus.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/PlayerStatu.java similarity index 50% rename from SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/PlayerStatus.java rename to SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/PlayerStatu.java index a39e3c7e02469de6ec5b20c414fb5eea6cb82ea1..8c43c509012fd0f0a84611436dee8e4eb3c785d0 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/PlayerStatus.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/constant/PlayerStatu.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,73 +17,55 @@ package com.huawei.codelab.player.constant; /** - * PlayerStatus enum + * PlayerStatu enum * - * @since 2020-12-04 + * @since 2021-04-04 * */ -public enum PlayerStatus { +public enum PlayerStatu { /** - * the video is released + * idel * */ - IDEL("idel"), - + IDEL, /** - * video is preparing + * preparing * */ - PREPARING("preparing"), - + PREPARING, /** - * when the video become prepared will be ready to play + * prepared * */ - PREPARED("prepared"), - + PREPARED, /** - * start the video or resume to play + * play * */ - PLAY("play"), - + PLAY, /** - * pause the playing + * pause * */ - PAUSE("pause"), - + PAUSE, /** - * stop the playing + * stop * */ - STOP("stop"), - + STOP, /** - * the video play completed + * complete * */ - COMPLETE("complete"), - + COMPLETE, /** - * the wrong status of video + * error * */ - ERROR("error"), - + ERROR, /** - * before the status of play + * buffering * */ - BUFFERING("buffering"); - - private String status; - - PlayerStatus(String value) { - this.status = value; - } - - public String getStatus() { - return status; - } + BUFFERING } diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/factory/SourceFactory.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/factory/SourceFactory.java index 9c1077c3b8511c7cc973c3fa2bfd9c25704c8ff3..e186decf1ae892642b790f4d3702f1f75dd04b25 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/factory/SourceFactory.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/factory/SourceFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ import java.io.IOException; /** * SourceFactory * - * @since 2020-12-04 + * @since 2021-04-04 * */ public class SourceFactory { @@ -78,9 +78,9 @@ public class SourceFactory { } /** - * getSource of Source + * getSource * - * @return Source + * @return Source Source */ public Source getSource() { return mPlayerSource; diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/manager/GestureDetector.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/manager/GestureDetector.java new file mode 100644 index 0000000000000000000000000000000000000000..d5c19e9c1a3fd924c14cad6dcd0394bf48a531ee --- /dev/null +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/manager/GestureDetector.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + */ + +package com.huawei.codelab.player.manager; + +import com.huawei.codelab.player.constant.Constants; +import com.huawei.codelab.player.constant.GestureConst; + +import ohos.agp.components.VelocityDetector; +import ohos.multimodalinput.event.TouchEvent; + +/** + * GestureDetector + * + * @since 2021-04-09 + */ +public class GestureDetector { + /** + * MOVING_HORIZONTAL + */ + public static final int MOVING_HORIZONTAL = 0; + /** + * MOVING_VERTICAL + */ + public static final int MOVING_VERTICAL = 1; + private int currentMoveType; + + /** + * OnGestureListener + * + * @since 2021-04-09 + */ + public interface OnGestureListener { + /** + * 开始滚动时回调 + * + * @param windowX 手指移动时x位置 + * @param windowY 手指移动时y位置 + * @return is deliver + */ + boolean onTouchBegin(float windowX, float windowY); + + /** + * 发生滚动时回调 + * + * @param direction 移动方向 0:横向 1:纵向 + * @param windowX 手指移动时x位置 + * @param windowY 手指移动时y位置 + * @param distance 移动距离 + * @return is deliver + */ + boolean onTouchMoving(int direction, float windowX, float windowY, float distance); + + /** + * 结束滚动时回调 + * + * @param direction 移动方向 0:横向 1:纵向 + * @return is deliver + */ + boolean onTouchCancel(int direction); + } + + private final OnGestureListener mListener; + + private float mLastFocusX; + private float mLastFocusY; + private float mDownFocusX; + private float mDownFocusY; + + private VelocityDetector mVelocityTracker; + + /** + * GestureDetector + * + * @param listener listener + */ + public GestureDetector(OnGestureListener listener) { + mListener = listener; + } + + /** + * onTouchEvent + * + * @param ev ev + * @return boolean + */ + public boolean onTouchEvent(TouchEvent ev) { + final int action = ev.getAction(); + addVelocityDetector(ev); + float[] points = getFocusPoint(ev); + final float focusX = points[0]; + final float focusY = points[1]; + boolean isHandled = true; + switch (action) { + case TouchEvent.OTHER_POINT_DOWN: + case TouchEvent.PRIMARY_POINT_DOWN: + currentMoveType = Constants.NUMBER_NEGATIVE_1; + mDownFocusX = 0; + mDownFocusY = 0; + mListener.onTouchBegin(focusX, focusY); + break; + case TouchEvent.POINT_MOVE: + if (mDownFocusX == 0 || mDownFocusY == 0) { + mDownFocusX = focusX; + mDownFocusY = focusY; + mLastFocusX = focusX; + mLastFocusY = focusY; + } + final int deltaX = (int) (focusX - mDownFocusX); + final int deltaY = (int) (focusY - mDownFocusY); + int distanceX = Math.abs(deltaX); + int distanceY = Math.abs(deltaY); + if (distanceX > GestureConst.getScaledTouchSlop() || distanceY > GestureConst.getScaledTouchSlop()) { + if (distanceX >= distanceY) { + currentMoveType = MOVING_HORIZONTAL; + float scrollX = mLastFocusX - focusX; + isHandled = mListener.onTouchMoving(MOVING_HORIZONTAL, focusX, focusY, scrollX); + } else { + currentMoveType = MOVING_VERTICAL; + float scrollY = mLastFocusY - focusY; + isHandled = mListener.onTouchMoving(MOVING_VERTICAL, focusX, focusY, scrollY); + } + mLastFocusX = focusX; + mLastFocusY = focusY; + } + break; + case TouchEvent.PRIMARY_POINT_UP: + case TouchEvent.OTHER_POINT_UP: + case TouchEvent.CANCEL: + isHandled = mListener.onTouchCancel(currentMoveType); + break; + default: + break; + } + return isHandled; + } + + private void addVelocityDetector(TouchEvent ev) { + if (mVelocityTracker == null) { + mVelocityTracker = VelocityDetector.obtainInstance(); + } + mVelocityTracker.addEvent(ev); + } + + private float[] getFocusPoint(TouchEvent ev) { + final boolean isPointerUp = ev.getAction() == TouchEvent.OTHER_POINT_UP; + final int skipIndex = isPointerUp ? ev.getIndex() : Constants.NUMBER_NEGATIVE_1; + float sumX = 0; + float sumY = 0; + final int count = ev.getPointerCount(); + for (int i = 0; i < count; i++) { + if (skipIndex == i) { + continue; + } + sumX += ev.getPointerPosition(i).getX(); + sumY += ev.getPointerPosition(i).getY(); + } + final int div = isPointerUp ? count - 1 : count; + float focusX = sumX / div; + float focusY = sumY / div; + return new float[]{focusX, focusY}; + } +} diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/manager/HmPlayerLifecycle.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/manager/HmPlayerLifecycle.java index 508377e74b991a5ae16b4d59914c6906b06d1135..8ed81c05d40c58fb0f49a77b6aae4c9a3aba83d9 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/manager/HmPlayerLifecycle.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/manager/HmPlayerLifecycle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,28 +16,27 @@ package com.huawei.codelab.player.manager; -import com.huawei.codelab.util.LogUtil; import com.huawei.codelab.player.api.ImplLifecycle; import com.huawei.codelab.player.api.ImplPlayer; -import com.huawei.codelab.player.constant.PlayerStatus; +import com.huawei.codelab.player.constant.PlayerStatu; /** * HmPlayerLifecycle * - * @since 2020-12-04 + * @since 2021-04-09 + * */ public class HmPlayerLifecycle implements ImplLifecycle { private static final String TAG = HmPlayerLifecycle.class.getSimpleName(); - private ImplPlayer player; - private boolean isBackGround; + private ImplPlayer mPlayer; /** - * constructor of HmPlayerLifecycle + * HmPlayerLifecycle * * @param player player */ public HmPlayerLifecycle(ImplPlayer player) { - this.player = player; + mPlayer = player; } @Override @@ -46,27 +45,20 @@ public class HmPlayerLifecycle implements ImplLifecycle { @Override public void onForeground() { - if (isBackGround) { - String url = player.getBuilder().getFilePath(); - int startTime = player.getBuilder().getStartMillisecond(); - player.reload(url, startTime); - isBackGround = false; - } + String url = mPlayer.getBuilder().getFilePath(); + int startMillisecond = mPlayer.getBuilder().getStartMillisecond(); + mPlayer.reload(url, startMillisecond); } @Override public void onBackground() { - if (!isBackGround) { - LogUtil.info(TAG, "onBackground is called ,palyer status is " + player.getPlayerStatu().getStatus()); - player.getBuilder().setPause(player.getPlayerStatu() == PlayerStatus.PAUSE); - player.getBuilder().setFilePath(player.getBuilder().getFilePath()); - player.getBuilder().setStartMillisecond(player.getAudioCurrentPosition()); - player.release(); - isBackGround = true; - } + mPlayer.getBuilder().setPause(mPlayer.getPlayerStatu() == PlayerStatu.PAUSE); + mPlayer.getBuilder().setStartMillisecond(mPlayer.getCurrentPosition()); + mPlayer.release(); } @Override public void onStop() { + mPlayer.release(); } } diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/util/CommonUtils.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/util/CommonUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..e3f589af90cf2639f5b12a45d7a80c9ec77ef300 --- /dev/null +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/util/CommonUtils.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.huawei.codelab.player.util; + +import com.huawei.codelab.player.constant.Constants; +import com.huawei.codelab.util.LogUtil; + +import ohos.app.Context; +import ohos.global.resource.NotExistException; +import ohos.global.resource.WrongTypeException; + +import java.io.IOException; + +/** + * Common util + * + * @since 2021-04-04 + */ +public class CommonUtils { + private static final String TAG = CommonUtils.class.getSimpleName(); + + private CommonUtils() { + } + + /** + * 通过资源ID获取颜色 + * + * @param context comtext + * @param resourceId id + * @return int + */ + public static int getColor(Context context, int resourceId) { + try { + return context.getResourceManager().getElement(resourceId).getColor(); + } catch (IOException | NotExistException | WrongTypeException e) { + LogUtil.error(TAG, e.getMessage()); + } + return Constants.NUMBER_NEGATIVE_1; + } +} diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/DateUtils.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/util/DateUtils.java similarity index 91% rename from SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/DateUtils.java rename to SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/util/DateUtils.java index b18a33804a3a4d49a2c26f5a985300972847a6ee..8b83ee326f3312f9bfd0af98cb77ee22306bdeb7 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/DateUtils.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/util/DateUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,15 +14,14 @@ * limitations under the License. */ -package com.huawei.codelab.util; +package com.huawei.codelab.player.util; import java.util.Locale; /** * Date util * - * @since 2020-12-04 - * + * @since 2021-04-04 */ public class DateUtils { private static final int ONE_SECONDS_MS = 1000; @@ -35,7 +34,7 @@ public class DateUtils { } /** - * conversion of msToString + * conversion of msToString * * @param ms ms * @return string diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/PlayerGestureView.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/PlayerGestureView.java new file mode 100644 index 0000000000000000000000000000000000000000..af65e967b7de868dc01ee8467794ad5902934036 --- /dev/null +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/PlayerGestureView.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + */ + +package com.huawei.codelab.player.view; + +import com.huawei.codelab.ResourceTable; +import com.huawei.codelab.player.api.ImplPlayModule; +import com.huawei.codelab.player.api.ImplPlayer; +import com.huawei.codelab.player.constant.Constants; +import com.huawei.codelab.player.constant.PlayerStatu; +import com.huawei.codelab.player.manager.GestureDetector; +import com.huawei.codelab.player.util.CommonUtils; +import com.huawei.codelab.player.util.DateUtils; + +import ohos.agp.colors.RgbColor; +import ohos.agp.components.AttrSet; +import ohos.agp.components.DirectionalLayout; +import ohos.agp.components.Image; +import ohos.agp.components.Text; +import ohos.agp.components.element.ShapeElement; +import ohos.agp.utils.Color; +import ohos.agp.utils.LayoutAlignment; +import ohos.app.Context; + +/** + * PlayerGestureView + * + * @since 2021-04-04 + */ +public class PlayerGestureView extends DirectionalLayout implements ImplPlayModule, GestureDetector.OnGestureListener { + private static final int MOVING_TYPE_INIT = -1; + private static final int VOLUME_TYPE = 0; + private static final int PROGRESS_DOWN_TYPE = 1; + private static final int PROGRESS_UP_TYPE = 2; + private static final int LIGHT_BRIGHT_TYPE = 3; + private ImplPlayer player; + private int currentPercent; + private int currentMoveType; + private int beginPosition; + + private Image gestureImage; + private Text gestureText; + + /** + * constructor of PlayerGestureView + * + * @param context context + */ + public PlayerGestureView(Context context) { + this(context, null); + } + + /** + * constructor of PlayerGestureView + * + * @param context context + * @param attrSet attSet + */ + public PlayerGestureView(Context context, AttrSet attrSet) { + this(context, attrSet, null); + } + + /** + * constructor of PlayerGestureView + * + * @param context context + * @param attrSet attSet + * @param styleName styleName + */ + public PlayerGestureView(Context context, AttrSet attrSet, String styleName) { + super(context, attrSet, styleName); + initView(); + hide(); + } + + private void initView() { + ShapeElement shapeElement = new ShapeElement(); + shapeElement.setRgbColor( + RgbColor.fromArgbInt(CommonUtils.getColor(mContext, ResourceTable.Color_half_transparent))); + shapeElement.setCornerRadius(Constants.NUMBER_25); + setOrientation(DirectionalLayout.VERTICAL); + setAlignment(LayoutAlignment.HORIZONTAL_CENTER); + setBackground(shapeElement); + gestureImage = new Image(mContext); + gestureImage.setWidth(Constants.NUMBER_150); + gestureImage.setHeight(Constants.NUMBER_150); + gestureImage.setScaleMode(Image.ScaleMode.STRETCH); + gestureImage.setMarginsTopAndBottom(Constants.NUMBER_40, Constants.NUMBER_10); + gestureText = new Text(mContext); + gestureText.setTextSize(Constants.NUMBER_36); + gestureText.setTextColor(new Color(CommonUtils.getColor(mContext, ResourceTable.Color_white))); + gestureText.setMarginsTopAndBottom(Constants.NUMBER_10, Constants.NUMBER_40); + addComponent(gestureImage); + addComponent(gestureText); + } + + private void show(int type, String content) { + int gestureImg = ResourceTable.Media_ic_horns; + switch (type) { + case VOLUME_TYPE: + gestureImg = ResourceTable.Media_ic_horns; + break; + case PROGRESS_DOWN_TYPE: + gestureImg = ResourceTable.Media_ic_backward; + break; + case PROGRESS_UP_TYPE: + gestureImg = ResourceTable.Media_ic_forward; + break; + case LIGHT_BRIGHT_TYPE: + gestureImg = ResourceTable.Media_ic_bright; + break; + default: + break; + } + gestureImage.setPixelMap(gestureImg); + gestureText.setText(content); + if (getVisibility() != VISIBLE) { + setVisibility(VISIBLE); + } + } + + private void hide() { + if (getVisibility() == VISIBLE) { + setVisibility(HIDE); + } + } + + @Override + public void bind(ImplPlayer implPlayer) { + this.player = implPlayer; + this.player.addPlayerStatuCallback(statu -> { + mContext.getUITaskDispatcher().asyncDispatch(() -> { + if (statu == PlayerStatu.STOP || statu == PlayerStatu.COMPLETE) { + hide(); + } + }); + }); + } + + @Override + public void unbind() { + } + + @Override + public boolean onTouchBegin(float focusX, float focusY) { + if (player != null) { + currentPercent = 0; + currentMoveType = MOVING_TYPE_INIT; + beginPosition = player.getCurrentPosition(); + } + return true; + } + + @Override + public boolean onTouchMoving(int direction, float focusX, float focusY, float distance) { + if (currentMoveType == MOVING_TYPE_INIT) { + currentMoveType = direction; + } + if (currentMoveType == direction && player != null) { + if (currentMoveType == GestureDetector.MOVING_HORIZONTAL) { + currentPercent += distance < 0 ? Constants.NUMBER_1000 : -Constants.NUMBER_1000; + int type = currentPercent < 0 + ? PlayerGestureView.PROGRESS_DOWN_TYPE : PlayerGestureView.PROGRESS_UP_TYPE; + int value = Math.abs(currentPercent); + String content = (currentPercent < 0 ? "- " : "+ ") + DateUtils.msToString(value); + show(type, content); + } else if (currentMoveType == GestureDetector.MOVING_VERTICAL) { + int interval = getHeight() / Constants.NUMBER_2; + if (focusX <= getWidth() / Constants.NUMBER_FLOAT_2) { + show(PlayerGestureView.LIGHT_BRIGHT_TYPE, "100%"); + } else { + float volume = player.getVolume() + distance / interval; + volume = (volume < 0) ? 0 : Math.min(volume, 1); + show(PlayerGestureView.VOLUME_TYPE, (int) (volume * Constants.NUMBER_100) + "%"); + player.setVolume(volume); + } + } else { + return false; + } + } + return true; + } + + @Override + public boolean onTouchCancel(int direction) { + if (currentMoveType == GestureDetector.MOVING_HORIZONTAL && player != null) { + player.rewindTo(beginPosition + currentPercent); + } + hide(); + return true; + } +} diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/component/PlayerLoading.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/PlayerLoading.java similarity index 38% rename from SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/component/PlayerLoading.java rename to SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/PlayerLoading.java index bcb4f32235c46e8ece164a489e01f9d05b4160b7..18238ada4556dce307d9abb2ae16e5b67a478a7d 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/component/PlayerLoading.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/PlayerLoading.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,101 +14,112 @@ * limitations under the License. */ -package com.huawei.codelab.player.component; +package com.huawei.codelab.player.view; import com.huawei.codelab.ResourceTable; +import com.huawei.codelab.player.api.ImplPlayModule; import com.huawei.codelab.player.api.ImplPlayer; -import com.huawei.codelab.player.api.StatusChangeListener; -import com.huawei.codelab.player.constant.PlayerStatus; -import com.huawei.codelab.util.LogUtil; import ohos.agp.animation.AnimatorProperty; +import ohos.agp.components.AttrSet; import ohos.agp.components.Component; +import ohos.agp.components.Component.TouchEventListener; import ohos.agp.components.ComponentContainer; -import ohos.agp.components.DependentLayout; import ohos.agp.components.Image; import ohos.agp.components.LayoutScatter; import ohos.app.Context; +import ohos.multimodalinput.event.TouchEvent; /** * PlayerLoading * - * @since 2020-12-04 + * @since 2021-04-04 */ -public class PlayerLoading extends ComponentContainer { +public class PlayerLoading extends ComponentContainer implements ImplPlayModule, TouchEventListener { private static final int HALF_NUMBER = 2; private static final int ANIM_ROTATE = 360; private static final int ANIM_DURATION = 2000; private static final int ANIM_LOOPED_COUNT = -1; - private ImplPlayer player; - private Image loading; - private AnimatorProperty loadingAnim; + private ImplPlayer mPlayer; + private Image mLoading; + private AnimatorProperty mLoadingAnim; /** * constructor of PlayerLoading * - * @param context builder - * @param player player + * @param context context */ - public PlayerLoading(Context context, ImplPlayer player) { - super(context); - this.player = player; - initComponent(context); - initListener(); + public PlayerLoading(Context context) { + this(context, null); + } + + /** + * constructor of PlayerLoading + * + * @param context context + * @param attrSet attSet + */ + public PlayerLoading(Context context, AttrSet attrSet) { + this(context, attrSet, null); + } + + /** + * constructor of PlayerLoading + * + * @param context context + * @param attrSet attSet + * @param styleName styleName + */ + public PlayerLoading(Context context, AttrSet attrSet, String styleName) { + super(context, attrSet, styleName); + initView(context); } - private void initComponent(Context context) { - DependentLayout.LayoutConfig layoutConfig = - new DependentLayout.LayoutConfig(DependentLayout.LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT); - setLayoutConfig(layoutConfig); - Component loadingContainer = LayoutScatter.getInstance(context).parse( - ResourceTable.Layout_player_loading_layout, null, false); + private void initView(Context context) { + Component loadingContainer = + LayoutScatter.getInstance(context).parse(ResourceTable.Layout_player_loading_layout, null, false); if (loadingContainer.findComponentById(ResourceTable.Id_image_loading) instanceof Image) { - loading = (Image) loadingContainer.findComponentById(ResourceTable.Id_image_loading); + mLoading = (Image) loadingContainer.findComponentById(ResourceTable.Id_image_loading); + initAnim(); } addComponent(loadingContainer); - initAnim(); hide(); + setTouchEventListener(this); } private void initAnim() { - int with = loading.getWidth() / HALF_NUMBER; - int height = loading.getHeight() / HALF_NUMBER; - loading.setPivotX(with); - loading.setPivotY(height); - loadingAnim = loading.createAnimatorProperty(); - loadingAnim.rotate(ANIM_ROTATE).setDuration(ANIM_DURATION).setLoopedCount(ANIM_LOOPED_COUNT); + int with = mLoading.getWidth() / HALF_NUMBER; + int height = mLoading.getHeight() / HALF_NUMBER; + mLoading.setPivotX(with); + mLoading.setPivotY(height); + mLoadingAnim = mLoading.createAnimatorProperty(); + mLoadingAnim.rotate(ANIM_ROTATE).setDuration(ANIM_DURATION).setLoopedCount(ANIM_LOOPED_COUNT); } private void initListener() { - player.addPlayerStatusCallback(new StatusChangeListener() { - @Override - public void statusCallback(PlayerStatus status) { - mContext.getUITaskDispatcher().delayDispatch( - new Runnable() { - @Override - public void run() { - if (status == PlayerStatus.PREPARING || status == PlayerStatus.BUFFERING) { - show(); - } else if (status == PlayerStatus.PLAY) { - hide(); - } else { - LogUtil.info(PlayerLoading.class.getName(), "statuCallback else message"); - } - } - }, 0); + mPlayer.addPlayerStatuCallback(statu -> mContext.getUITaskDispatcher().asyncDispatch(() -> { + switch (statu) { + case PREPARING: + case BUFFERING: + show(); + break; + case PLAY: + hide(); + break; + default: + break; } - }); + })); } /** * show of PlayerLoading */ public void show() { - if (loadingAnim.isPaused()) { - loadingAnim.resume(); + if (mLoadingAnim.isPaused()) { + mLoadingAnim.resume(); } else { - loadingAnim.start(); + mLoadingAnim.start(); } setVisibility(VISIBLE); } @@ -118,6 +129,22 @@ public class PlayerLoading extends ComponentContainer { */ public void hide() { setVisibility(INVISIBLE); - loadingAnim.pause(); + mLoadingAnim.pause(); + } + + @Override + public void bind(ImplPlayer player) { + mPlayer = player; + initListener(); + } + + @Override + public void unbind() { + mLoadingAnim.release(); + } + + @Override + public boolean onTouchEvent(Component component, TouchEvent touchEvent) { + return true; } } diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/PlayerView.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/PlayerView.java new file mode 100644 index 0000000000000000000000000000000000000000..f5cf9c774692b4195b7c7b7de4ad2d03a669f79c --- /dev/null +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/PlayerView.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + */ + +package com.huawei.codelab.player.view; + +import com.huawei.codelab.player.api.ImplPlayModule; +import com.huawei.codelab.player.api.ImplPlayer; +import com.huawei.codelab.player.constant.Constants; +import com.huawei.codelab.player.manager.GestureDetector; + +import ohos.agp.components.Attr; +import ohos.agp.components.AttrSet; +import ohos.agp.components.Component; +import ohos.agp.components.Component.LayoutRefreshedListener; +import ohos.agp.components.ComponentContainer; +import ohos.agp.components.DependentLayout; +import ohos.agp.components.surfaceprovider.SurfaceProvider; +import ohos.agp.graphics.Surface; +import ohos.agp.graphics.SurfaceOps; +import ohos.agp.window.service.WindowManager; +import ohos.app.Context; + +import java.util.Optional; + +/** + * PlayerView + * + * @since 2021-04-04 + */ +public class PlayerView extends DependentLayout implements ImplPlayModule, LayoutRefreshedListener { + private ImplPlayer player; + private SurfaceProvider surfaceView; + private Surface surface; + private PlayerGestureView gestureView; + private GestureDetector gestureDetector; + private boolean isTopPlay; + private int viewWidth; + private int viewHeight; + + /** + * constructor of PlayerView + * + * @param context context + */ + public PlayerView(Context context) { + this(context, null); + } + + /** + * constructor of PlayerView + * + * @param context context + * @param attrSet attSet + */ + public PlayerView(Context context, AttrSet attrSet) { + this(context, attrSet, null); + } + + /** + * constructor of PlayerView + * + * @param context context + * @param attrSet attSet + * @param styleName styleName + */ + public PlayerView(Context context, AttrSet attrSet, String styleName) { + super(context, attrSet, styleName); + WindowManager.getInstance().getTopWindow().get().setTransparent(true); // 不设置窗体透明会挡住播放内容,除非设置pinToZTop为true + if (attrSet != null) { + Optional optIsTopPlay = attrSet.getAttr("top_play"); + optIsTopPlay.ifPresent(attr -> isTopPlay = "true".equals(attr.getStringValue())); + } + initView(); + initListener(); + setLayoutRefreshedListener(this); + } + + private void initView() { + surfaceView = new SurfaceProvider(mContext); + DependentLayout.LayoutConfig layoutConfig = new DependentLayout.LayoutConfig(); + layoutConfig.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT); + surfaceView.setLayoutConfig(layoutConfig); + surfaceView.pinToZTop(isTopPlay); + addComponent(surfaceView); + addGestureView(); + } + + private void addGestureView() { + gestureView = new PlayerGestureView(mContext); + DependentLayout.LayoutConfig config = + new DependentLayout.LayoutConfig(Constants.NUMBER_300, ComponentContainer.LayoutConfig.MATCH_CONTENT); + config.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT); + gestureView.setLayoutConfig(config); + addComponent(gestureView); + } + + private void initListener() { + gestureDetector = new GestureDetector(gestureView); + surfaceView.setTouchEventListener((component, touchEvent) -> + canGesture() && gestureDetector.onTouchEvent(touchEvent)); + surfaceView.getSurfaceOps().ifPresent(surfaceOps -> surfaceOps.addCallback(new SurfaceOps.Callback() { + @Override + public void surfaceCreated(SurfaceOps surfaceOps) { + surface = surfaceOps.getSurface(); + if (player != null) { + player.addSurface(surface); + } + } + + @Override + public void surfaceChanged(SurfaceOps surfaceOps, int info, int width, int height) { + } + + @Override + public void surfaceDestroyed(SurfaceOps surfaceOps) { + } + })); + } + + private boolean canGesture() { + return gestureDetector != null + && player != null + && player.isGestureOpen(); + } + + private void updateVideoSize(double videoScale) { + if (videoScale > 1) { + surfaceView.setWidth(viewWidth); + surfaceView.setHeight((int) Math.min(viewWidth / videoScale, viewHeight)); + } else { + surfaceView.setHeight(viewHeight); + surfaceView.setWidth((int) Math.min(viewHeight * videoScale, viewWidth)); + } + } + + @Override + public void bind(ImplPlayer implPlayer) { + this.player = implPlayer; + gestureView.bind(player); + this.player.addPlayerViewCallback((width, height) -> mContext.getUITaskDispatcher().asyncDispatch(() -> { + if (width > 0) { + setWidth(width); + } + if (height > 0) { + setHeight(height); + } + })); + } + + @Override + public void unbind() { + surfaceView.removeFromWindow(); + surfaceView = null; + surface = null; + } + + @Override + public void onRefreshed(Component component) { + int newWidth = component.getWidth(); + int newHeight = component.getHeight(); + double videoScale = player.getVideoScale(); + if (videoScale != Constants.NUMBER_NEGATIVE_1 && (newWidth != viewWidth || newHeight != viewHeight)) { + viewWidth = newWidth; + viewHeight = newHeight; + mContext.getUITaskDispatcher().asyncDispatch(() -> updateVideoSize(videoScale)); + } + } +} diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/component/SimplePlayerController.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/SimplePlayerController.java similarity index 33% rename from SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/component/SimplePlayerController.java rename to SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/SimplePlayerController.java index e8e8f213d14bd9eec854b0ab23eb9f459129bbac..421e9c654819b59ae82410b3130b32f0ff2a3c60 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/component/SimplePlayerController.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/player/view/SimplePlayerController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,19 +14,22 @@ * limitations under the License. */ -package com.huawei.codelab.player.component; +package com.huawei.codelab.player.view; import com.huawei.codelab.ResourceTable; +import com.huawei.codelab.player.api.ImplPlayModule; import com.huawei.codelab.player.api.ImplPlayer; -import com.huawei.codelab.player.api.StatusChangeListener; +import com.huawei.codelab.player.api.StatuChangeListener; import com.huawei.codelab.player.constant.Constants; -import com.huawei.codelab.player.constant.PlayerStatus; -import com.huawei.codelab.util.DateUtils; -import com.huawei.codelab.util.LogUtil; +import com.huawei.codelab.player.constant.PlayerStatu; +import com.huawei.codelab.player.util.DateUtils; import ohos.agp.colors.RgbColor; +import ohos.agp.components.AttrSet; import ohos.agp.components.Component; import ohos.agp.components.ComponentContainer; +import ohos.agp.components.DependentLayout; +import ohos.agp.components.DirectionalLayout; import ohos.agp.components.Image; import ohos.agp.components.LayoutScatter; import ohos.agp.components.Slider; @@ -40,9 +43,9 @@ import ohos.eventhandler.InnerEvent; /** * PlayerController * - * @since 2020-12-04 + * @since 2021-04-04 */ -public class SimplePlayerController extends ComponentContainer { +public class SimplePlayerController extends ComponentContainer implements ImplPlayModule { private static final int THUMB_RED = 255; private static final int THUMB_GREEN = 255; private static final int THUMB_BLUE = 240; @@ -51,69 +54,85 @@ public class SimplePlayerController extends ComponentContainer { private static final int THUMB_RADIUS = 20; private static final int CONTROLLER_HIDE_DLEY_TIME = 5000; private static final int PROGRESS_RUNNING_TIME = 1000; - private boolean isDragMode = false; - private Context context; - private ImplPlayer implPlayer; - private Image playToggle; - private Image imageForward; - private Image imageBackward; - private Slider progressBar; - private Text currentTime; - private Text totleTime; - private ControllerHandler controllerHandler; - private StatusChangeListener statusChangeListener = new StatusChangeListener() { + private boolean mIsDragMode = false; + private Context mContext; + private ImplPlayer mPlayer; + private DependentLayout topLayout; + private DirectionalLayout bottomLayout; + private Image mBack; + private Image mPlayToogle; + private Image mForward; + private Image mBackward; + private Slider mProgressBar; + private Text mCurrentTime; + private Text mTotleTime; + private ControllerHandler mHandler; + private StatuChangeListener mStatuChangeListener = new StatuChangeListener() { @Override - public void statusCallback(PlayerStatus status) { - context.getUITaskDispatcher().delayDispatch( - new Runnable() { - @Override - public void run() { - controllerHandler.removeEvent(Constants.PLAYER_PROGRESS_RUNNING); - if (status == PlayerStatus.PREPARING) { - playToggle.setClickable(false); - progressBar.setEnabled(false); - progressBar.setProgressValue(0); - } else if (status == PlayerStatus.PREPARED) { - progressBar.setMaxValue(implPlayer.getAudioDuration()); - totleTime.setText(implPlayer.getDurationText()); - } else if (status == PlayerStatus.PLAY) { - controllerHandler.sendEvent( - Constants.PLAYER_PROGRESS_RUNNING, - EventHandler.Priority.IMMEDIATE); - playToggle.setPixelMap(ResourceTable.Media_ic_music_stop); - playToggle.setClickable(true); - progressBar.setEnabled(true); - } else if (status == PlayerStatus.PAUSE) { - controllerHandler.sendEvent( - Constants.PLAYER_PROGRESS_RUNNING, - EventHandler.Priority.IMMEDIATE); - playToggle.setPixelMap(ResourceTable.Media_ic_music_play); - } else if (status == PlayerStatus.STOP || status == PlayerStatus.COMPLETE) { - controllerHandler.sendEvent( - Constants.PLAYER_PROGRESS_RUNNING, - EventHandler.Priority.IMMEDIATE); - playToggle.setPixelMap(ResourceTable.Media_ic_update); - progressBar.setEnabled(false); - } else { - LogUtil.info(SimplePlayerController.class.getName(), "statuCallback else message"); - } - } - }, 0); + public void statuCallback(PlayerStatu statu) { + mContext.getUITaskDispatcher().asyncDispatch(() -> { + switch (statu) { + case PREPARING: + mPlayToogle.setClickable(false); + mProgressBar.setEnabled(false); + mProgressBar.setProgressValue(0); + break; + case PREPARED: + mProgressBar.setMaxValue(mPlayer.getDuration()); + mTotleTime.setText(DateUtils.msToString(mPlayer.getDuration())); + break; + case PLAY: + showController(false); + mPlayToogle.setPixelMap(ResourceTable.Media_ic_music_stop); + mPlayToogle.setClickable(true); + mProgressBar.setEnabled(true); + break; + case PAUSE: + mPlayToogle.setPixelMap(ResourceTable.Media_ic_music_play); + break; + case STOP: + case COMPLETE: + mPlayToogle.setPixelMap(ResourceTable.Media_ic_update); + mProgressBar.setEnabled(false); + break; + default: + break; + } + }); } }; /** - * constructor of PlayerController + * constructor of SimplePlayerController + * + * @param context context + */ + public SimplePlayerController(Context context) { + this(context, null); + } + + /** + * constructor of SimplePlayerController + * + * @param context context + * @param attrSet attSet + */ + public SimplePlayerController(Context context, AttrSet attrSet) { + this(context, attrSet, null); + } + + /** + * constructor of SimplePlayerController * - * @param context builder - * @param player player + * @param context context + * @param attrSet attSet + * @param styleName styleName */ - public SimplePlayerController(Context context, ImplPlayer player) { - super(context); - this.context = context; - implPlayer = player; + public SimplePlayerController(Context context, AttrSet attrSet, String styleName) { + super(context, attrSet, styleName); + mContext = context; createHandler(); - initComponent(); + initView(); initListener(); } @@ -122,99 +141,97 @@ public class SimplePlayerController extends ComponentContainer { if (runner == null) { return; } - controllerHandler = new ControllerHandler(runner); + mHandler = new ControllerHandler(runner); } - private void initComponent() { - Component playerController = LayoutScatter.getInstance(context).parse( - ResourceTable.Layout_simple_player_controller_layout, null, false); + private void initView() { + Component playerController = + LayoutScatter.getInstance(mContext) + .parse(ResourceTable.Layout_simple_player_controller_layout, null, false); addComponent(playerController); + if (playerController.findComponentById(ResourceTable.Id_controller_top_layout) instanceof DependentLayout) { + topLayout = (DependentLayout) playerController.findComponentById(ResourceTable.Id_controller_top_layout); + } + if (playerController.findComponentById(ResourceTable.Id_controller_bottom_layout) + instanceof DirectionalLayout) { + bottomLayout = (DirectionalLayout) playerController + .findComponentById(ResourceTable.Id_controller_bottom_layout); + } + if (playerController.findComponentById(ResourceTable.Id_back) instanceof Image) { + mBack = (Image) playerController.findComponentById(ResourceTable.Id_back); + } if (playerController.findComponentById(ResourceTable.Id_play_controller) instanceof Image) { - playToggle = (Image) playerController.findComponentById(ResourceTable.Id_play_controller); + mPlayToogle = (Image) playerController.findComponentById(ResourceTable.Id_play_controller); } if (playerController.findComponentById(ResourceTable.Id_play_forward) instanceof Image) { - imageForward = (Image) playerController.findComponentById(ResourceTable.Id_play_forward); + mForward = (Image) playerController.findComponentById(ResourceTable.Id_play_forward); } if (playerController.findComponentById(ResourceTable.Id_play_backward) instanceof Image) { - imageBackward = (Image) playerController.findComponentById(ResourceTable.Id_play_backward); + mBackward = (Image) playerController.findComponentById(ResourceTable.Id_play_backward); } if (playerController.findComponentById(ResourceTable.Id_progress) instanceof Slider) { - progressBar = (Slider) playerController.findComponentById(ResourceTable.Id_progress); + mProgressBar = (Slider) playerController.findComponentById(ResourceTable.Id_progress); } ShapeElement shapeElement = new ShapeElement(); shapeElement.setRgbColor(new RgbColor(THUMB_RED, THUMB_GREEN, THUMB_BLUE)); shapeElement.setBounds(0, 0, THUMB_WIDTH, THUMB_HEIGHT); shapeElement.setCornerRadius(THUMB_RADIUS); - progressBar.setThumbElement(shapeElement); + mProgressBar.setThumbElement(shapeElement); if (playerController.findComponentById(ResourceTable.Id_current_time) instanceof Text) { - currentTime = (Text) playerController.findComponentById(ResourceTable.Id_current_time); + mCurrentTime = (Text) playerController.findComponentById(ResourceTable.Id_current_time); } if (playerController.findComponentById(ResourceTable.Id_end_time) instanceof Text) { - totleTime = (Text) playerController.findComponentById(ResourceTable.Id_end_time); + mTotleTime = (Text) playerController.findComponentById(ResourceTable.Id_end_time); } } private void initListener() { - implPlayer.addPlayerStatusCallback(statusChangeListener); - playToggle.setClickedListener(new ClickedListener() { - @Override - public void onClick(Component component) { - if (implPlayer.isPlaying()) { - implPlayer.pause(); - } else { - if (implPlayer.getPlayerStatu() == PlayerStatus.STOP) { - implPlayer.replay(); - } else { - implPlayer.resume(); - } - } - } - }); - imageForward.setClickedListener(new ClickedListener() { - @Override - public void onClick(Component component) { - implPlayer.rewindTo(implPlayer.getAudioCurrentPosition() + Constants.REWIND_STEP); - } - }); - imageBackward.setClickedListener(new ClickedListener() { - @Override - public void onClick(Component component) { - implPlayer.rewindTo(implPlayer.getAudioCurrentPosition() - Constants.REWIND_STEP); - } - }); - setValueChangedListener(); + topLayout.setTouchEventListener((component, touchEvent) -> true); + bottomLayout.setTouchEventListener((component, touchEvent) -> true); + mBack.setClickedListener(component -> mContext.terminateAbility()); } - private void setValueChangedListener() { - progressBar.setValueChangedListener(new Slider.ValueChangedListener() { - @Override - public void onProgressUpdated(Slider slider, int value, boolean isB) { - context.getUITaskDispatcher().delayDispatch( - new Runnable() { - @Override - public void run() { - currentTime.setText(DateUtils.msToString(value)); - } - }, 0); - } - - @Override - public void onTouchStart(Slider slider) { - isDragMode = true; - showController(false); - controllerHandler.removeEvent(Constants.PLAYER_PROGRESS_RUNNING, EventHandler.Priority.IMMEDIATE); - } - - @Override - public void onTouchEnd(Slider slider) { - isDragMode = false; - if (slider.getProgress() == implPlayer.getAudioDuration()) { - implPlayer.stop(); + private void initPlayListener() { + mPlayer.addPlayerStatuCallback(mStatuChangeListener); + mPlayToogle.setClickedListener(component -> { + if (mPlayer.isPlaying()) { + mPlayer.pause(); + } else { + if (mPlayer.getPlayerStatu() == PlayerStatu.STOP) { + mPlayer.replay(); } else { - implPlayer.rewindTo(slider.getProgress()); + mPlayer.resume(); } } }); + mForward.setClickedListener(component -> + mPlayer.rewindTo(mPlayer.getCurrentPosition() + Constants.REWIND_STEP)); + mBackward.setClickedListener(component -> + mPlayer.rewindTo(mPlayer.getCurrentPosition() - Constants.REWIND_STEP)); + mProgressBar.setValueChangedListener( + new Slider.ValueChangedListener() { + @Override + public void onProgressUpdated(Slider slider, int value, boolean isB) { + mContext.getUITaskDispatcher().asyncDispatch(() -> + mCurrentTime.setText(DateUtils.msToString(value))); + } + + @Override + public void onTouchStart(Slider slider) { + mIsDragMode = true; + mHandler.removeEvent(Constants.PLAYER_PROGRESS_RUNNING, EventHandler.Priority.IMMEDIATE); + } + + @Override + public void onTouchEnd(Slider slider) { + mIsDragMode = false; + if (slider.getProgress() == mPlayer.getDuration()) { + mPlayer.stop(); + } else { + mPlayer.rewindTo(slider.getProgress()); + } + } + }); } /** @@ -223,11 +240,11 @@ public class SimplePlayerController extends ComponentContainer { * @param isAutoHide isAutoHide */ public void showController(boolean isAutoHide) { - controllerHandler.sendEvent(Constants.PLAYER_CONTROLLER_SHOW, EventHandler.Priority.HIGH); + mHandler.sendEvent(Constants.PLAYER_CONTROLLER_SHOW, EventHandler.Priority.HIGH); if (isAutoHide) { hideController(CONTROLLER_HIDE_DLEY_TIME); } else { - controllerHandler.removeEvent(Constants.PLAYER_CONTROLLER_HIDE); + mHandler.removeEvent(Constants.PLAYER_CONTROLLER_HIDE); } } @@ -237,13 +254,26 @@ public class SimplePlayerController extends ComponentContainer { * @param delay delay */ public void hideController(int delay) { - controllerHandler.removeEvent(Constants.PLAYER_CONTROLLER_HIDE); - controllerHandler.sendEvent(Constants.PLAYER_CONTROLLER_HIDE, delay, EventHandler.Priority.HIGH); + mHandler.removeEvent(Constants.PLAYER_CONTROLLER_HIDE); + mHandler.sendEvent(Constants.PLAYER_CONTROLLER_HIDE, delay, EventHandler.Priority.HIGH); + } + + @Override + public void bind(ImplPlayer player) { + mPlayer = player; + initPlayListener(); + } + + @Override + public void unbind() { + mHandler.removeAllEvent(); + mHandler = null; } /** * ControllerHandler * + * @author chenweiquan * @since 2020-12-04 */ private class ControllerHandler extends EventHandler { @@ -259,44 +289,27 @@ public class SimplePlayerController extends ComponentContainer { } switch (event.eventId) { case Constants.PLAYER_PROGRESS_RUNNING: - context.getUITaskDispatcher() - .delayDispatch( - new Runnable() { - @Override - public void run() { - progressBar.setProgressValue(implPlayer.getAudioCurrentPosition()); - currentTime.setText(implPlayer.getCurrentText()); - } - }, - 0); - if (implPlayer.isPlaying() && !isDragMode) { - controllerHandler.sendEvent( + if (mPlayer != null && mPlayer.isPlaying() && !mIsDragMode) { + mContext.getUITaskDispatcher().asyncDispatch(() -> { + mProgressBar.setProgressValue(mPlayer.getCurrentPosition()); + mCurrentTime.setText(DateUtils.msToString(mPlayer.getCurrentPosition())); + }); + mHandler.sendEvent( Constants.PLAYER_PROGRESS_RUNNING, PROGRESS_RUNNING_TIME, Priority.IMMEDIATE); } break; case Constants.PLAYER_CONTROLLER_HIDE: - context.getUITaskDispatcher() - .delayDispatch( - new Runnable() { - @Override - public void run() { - setVisibility(INVISIBLE); - } - }, - 0); - controllerHandler.removeEvent(Constants.PLAYER_PROGRESS_RUNNING); + mContext.getUITaskDispatcher().asyncDispatch(() -> setVisibility(INVISIBLE)); + mHandler.removeEvent(Constants.PLAYER_PROGRESS_RUNNING); break; case Constants.PLAYER_CONTROLLER_SHOW: - controllerHandler.sendEvent(Constants.PLAYER_PROGRESS_RUNNING, Priority.IMMEDIATE); - context.getUITaskDispatcher() - .delayDispatch( - new Runnable() { - @Override - public void run() { - setVisibility(VISIBLE); - } - }, - 0); + mHandler.removeEvent(Constants.PLAYER_PROGRESS_RUNNING); + mHandler.sendEvent(Constants.PLAYER_PROGRESS_RUNNING, Priority.IMMEDIATE); + mContext.getUITaskDispatcher().asyncDispatch(() -> { + if (getVisibility() != VISIBLE) { + setVisibility(VISIBLE); + } + }); break; default: break; diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/slice/SimplePlayerAbilitySlice.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/slice/SimplePlayerAbilitySlice.java index beaf4b63b3f6de8efa26cd788be2e5f9ecc9a8fb..9002397fe2cb161100db30ea0ec3d8f36b2395b4 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/slice/SimplePlayerAbilitySlice.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/slice/SimplePlayerAbilitySlice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,98 +17,96 @@ package com.huawei.codelab.slice; import com.huawei.codelab.ResourceTable; -import com.huawei.codelab.player.constant.Constants; -import com.huawei.codelab.player.component.PlayerLoading; -import com.huawei.codelab.player.component.SimplePlayerController; -import com.huawei.codelab.util.AbilitySliceRouteUtil; -import com.huawei.codelab.util.LogUtil; import com.huawei.codelab.player.HmPlayer; import com.huawei.codelab.player.api.ImplPlayer; +import com.huawei.codelab.player.constant.Constants; +import com.huawei.codelab.player.view.PlayerLoading; +import com.huawei.codelab.player.view.PlayerView; +import com.huawei.codelab.player.view.SimplePlayerController; +import com.huawei.codelab.util.LogUtil; +import com.huawei.codelab.util.ScreenUtils; import ohos.aafwk.ability.AbilitySlice; -import ohos.aafwk.ability.fraction.Fraction; import ohos.aafwk.content.Intent; import ohos.agp.components.DependentLayout; +import ohos.app.dispatcher.task.TaskPriority; +import ohos.bundle.AbilityInfo; /** - * PlayerAbilitySlice + * SimplePlayerAbilitySlice * - * @since 2020-12-04 + * @since 2021-04-04 */ public class SimplePlayerAbilitySlice extends AbilitySlice { private static final String TAG = SimplePlayerAbilitySlice.class.getSimpleName(); - private static ImplPlayer implPlayer; - private int startMillisecond; + private ImplPlayer player; + private DependentLayout parentLayout; + private PlayerView playerView; + private PlayerLoading loadingView; + private SimplePlayerController controllerView; private String url = "entry/resources/base/media/gubeishuizhen.mp4"; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_simple_video_play_layout); - startMillisecond = intent.getIntParam(Constants.INTENT_STARTTIME_PARAM, 0); + player = new HmPlayer.Builder(this).setFilePath(url).create(); + player.getLifecycle().onStart(); initComponent(); - implPlayer.getLifecycle().onStart(); - } - - public static ImplPlayer getImplPlayer() { - return implPlayer; } private void initComponent() { - Fraction fraction = new Fraction(); - DependentLayout layout = null; if (findComponentById(ResourceTable.Id_parent) instanceof DependentLayout) { - layout = (DependentLayout) findComponentById(ResourceTable.Id_parent); + parentLayout = (DependentLayout) findComponentById(ResourceTable.Id_parent); } - - DependentLayout playerLayout = null; - if (findComponentById(ResourceTable.Id_parent_layout) instanceof DependentLayout) { - playerLayout = (DependentLayout) findComponentById(ResourceTable.Id_parent_layout); + if (findComponentById(ResourceTable.Id_player_view) instanceof PlayerView) { + playerView = (PlayerView) findComponentById(ResourceTable.Id_player_view); + } + if (findComponentById(ResourceTable.Id_loading_view) instanceof PlayerLoading) { + loadingView = (PlayerLoading) findComponentById(ResourceTable.Id_loading_view); } - implPlayer = new HmPlayer.Builder(this).setStartMillisecond(startMillisecond).setFilePath(url).create(); - SimplePlayerController simplePlayerController = new SimplePlayerController(this, implPlayer); - PlayerLoading playerLoading = new PlayerLoading(this, implPlayer); - playerLayout.addComponent(implPlayer.getPlayerView()); - playerLayout.addComponent(playerLoading); - playerLayout.addComponent(simplePlayerController); - implPlayer.play(); + if (findComponentById(ResourceTable.Id_controller_view) instanceof SimplePlayerController) { + controllerView = (SimplePlayerController) findComponentById(ResourceTable.Id_controller_view); + } + playerView.bind(player); + loadingView.bind(player); + controllerView.bind(player); } @Override - public void onActive() { - super.onActive(); - AbilitySliceRouteUtil.getInstance().addRoute(this); + protected void onOrientationChanged(AbilityInfo.DisplayOrientation displayOrientation) { + super.onOrientationChanged(displayOrientation); + int screenWidth = ScreenUtils.getScreenWidth(this); + parentLayout.setWidth(screenWidth); + player.openGesture(displayOrientation == AbilityInfo.DisplayOrientation.LANDSCAPE); } @Override - protected void onInactive() { - LogUtil.info(TAG, "onInactive is called"); - super.onInactive(); + public void onActive() { + super.onActive(); + getGlobalTaskDispatcher(TaskPriority.DEFAULT).delayDispatch(() -> player.play(), Constants.NUMBER_1000); } @Override public void onForeground(Intent intent) { - implPlayer.getLifecycle().onForeground(); + player.getLifecycle().onForeground(); super.onForeground(intent); } @Override protected void onBackground() { LogUtil.info(TAG, "onBackground is called"); - implPlayer.getLifecycle().onBackground(); + player.getLifecycle().onBackground(); super.onBackground(); } - @Override - protected void onBackPressed() { - super.onBackPressed(); - } - @Override protected void onStop() { LogUtil.info(TAG, "onStop is called"); - AbilitySliceRouteUtil.getInstance().removeRoute(this); - implPlayer.getLifecycle().onStop(); + loadingView.unbind(); + controllerView.unbind(); + playerView.unbind(); + player.getLifecycle().onStop(); super.onStop(); } } diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/AbilitySliceRouteUtil.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/AbilitySliceRouteUtil.java deleted file mode 100644 index 12838b43a3460bd748c9a256e3cdfd264eb68a0a..0000000000000000000000000000000000000000 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/AbilitySliceRouteUtil.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.huawei.codelab.util; - -import ohos.aafwk.ability.AbilitySlice; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * AbilitySliceRoute util - * - * @since 2020-12-04 - * - */ -public class AbilitySliceRouteUtil { - private static AbilitySliceRouteUtil instance; - - private List> routes; - - private AbilitySliceRouteUtil() { - routes = new ArrayList<>(0); - } - - /** - * initialization AbilitySliceRouteUtil - * - * @return AbilitySliceRouteUtil - */ - public static synchronized AbilitySliceRouteUtil getInstance() { - if (instance == null) { - instance = new AbilitySliceRouteUtil(); - } - return instance; - } - - /** - * add route - * - * @param slice slice - */ - public void addRoute(AbilitySlice slice) { - Map map = new HashMap<>(0); - map.put(slice.getClass().getName(), slice); - routes.add(map); - } - - /** - * remove Route - * - * @param slice slice - */ - public void removeRoute(AbilitySlice slice) { - String tag = slice.getClass().getName(); - for (int i = routes.size() - 1; i >= 0; i--) { - for (Map.Entry stringAbilitySliceEntry : routes.get(i).entrySet()) { - String key = null; - if (stringAbilitySliceEntry instanceof Map.Entry) { - if (((Map.Entry) stringAbilitySliceEntry).getKey() instanceof String) { - key = (String) ((Map.Entry) stringAbilitySliceEntry).getKey(); - } - } - if (tag.equals(key)) { - routes.remove(routes.get(i)); - break; - } - } - } - } - - /** - * terminateAbilitySlice method - */ - public void terminateAbilitySlice() { - for (int i = routes.size() - 1; i >= 0; i--) { - for (Map.Entry stringAbilitySliceEntry : routes.get(i).entrySet()) { - if (stringAbilitySliceEntry instanceof Map.Entry) { - if (((Map.Entry) stringAbilitySliceEntry).getValue() instanceof AbilitySlice) { - AbilitySlice abilitySlice = (AbilitySlice) ((Map.Entry) stringAbilitySliceEntry).getValue(); - abilitySlice.terminate(); - } - } - } - } - } -} diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/LogUtil.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/LogUtil.java index 2f251ab6e46cf3b8e93e3ecfc8710be3c406f051..2aa98e435c0ddbd243930d4a42aa81ef62eafc15 100644 --- a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/LogUtil.java +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/LogUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,8 +22,7 @@ import ohos.hiviewdfx.HiLogLabel; /** * Log util * - * @since 2020-12-04 - * + * @since 2021-04-04 */ public class LogUtil { private static final String TAG_LOG = "LogUtil"; @@ -32,7 +31,8 @@ public class LogUtil { private static final String LOG_FORMAT = "%{public}s: %{public}s"; - private LogUtil() {} + private LogUtil() { + } /** * Print debug log @@ -63,5 +63,4 @@ public class LogUtil { public static void error(String tag, String msg) { HiLog.error(LABEL_LOG, LOG_FORMAT, tag, msg); } - } diff --git a/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/ScreenUtils.java b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/ScreenUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..1725ff685418af5a64d66d74e6637d4bbb62cbcf --- /dev/null +++ b/SimpleVideoCodelab/entry/src/main/java/com/huawei/codelab/util/ScreenUtils.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.huawei.codelab.util; + +import ohos.agp.utils.Point; +import ohos.agp.window.service.Display; +import ohos.agp.window.service.DisplayManager; +import ohos.app.Context; +import ohos.global.configuration.DeviceCapability; + +import java.util.Optional; + +/** + * Screen util + * + * @since 2021-04-04 + */ +public class ScreenUtils { + private ScreenUtils() { + } + + /** + * getScreenHeight + * + * @param context context + * @return Screen Height + */ + public static int getScreenHeight(Context context) { + DisplayManager displayManager = DisplayManager.getInstance(); + Optional optDisplay = displayManager.getDefaultDisplay(context); + Point point = new Point(0, 0); + if (!optDisplay.isPresent()) { + return (int) point.position[1]; + } else { + Display display = optDisplay.get(); + display.getSize(point); + return (int) point.position[1]; + } + } + + /** + * getScreenWidth + * + * @param context context + * @return Screen Width + */ + public static int getScreenWidth(Context context) { + DisplayManager displayManager = DisplayManager.getInstance(); + Optional optDisplay = displayManager.getDefaultDisplay(context); + Point point = new Point(0, 0); + if (!optDisplay.isPresent()) { + return (int) point.position[0]; + } else { + Display display = optDisplay.get(); + display.getSize(point); + return (int) point.position[0]; + } + } + + /** + * dp2px + * + * @param context context + * @param size size + * @return int + */ + public static int dp2px(Context context, int size) { + int density = context.getResourceManager().getDeviceCapability().screenDensity / DeviceCapability.SCREEN_MDPI; + return size * density; + } + + /** + * px2dip + * + * @param context context + * @param size size + * @return int + */ + public static int px2dip(Context context, int size) { + int density = context.getResourceManager().getDeviceCapability().screenDensity / DeviceCapability.SCREEN_MDPI; + return size / density; + } +} diff --git a/SimpleVideoCodelab/entry/src/main/resources/base/graphic/button_element.xml b/SimpleVideoCodelab/entry/src/main/resources/base/graphic/button_element.xml deleted file mode 100644 index a82975988880a3ecb5a240395c645bba4f300891..0000000000000000000000000000000000000000 --- a/SimpleVideoCodelab/entry/src/main/resources/base/graphic/button_element.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/SimpleVideoCodelab/entry/src/main/resources/base/layout/main_layout.xml b/SimpleVideoCodelab/entry/src/main/resources/base/layout/main_layout.xml deleted file mode 100644 index 233673ae9670387b7f01650858e3b2fa0774a80a..0000000000000000000000000000000000000000 --- a/SimpleVideoCodelab/entry/src/main/resources/base/layout/main_layout.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - -