@quicktvui/ai 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/rules/.clinerules +27 -4
- package/rules/.cursorrules +27 -4
- package/rules/.github/copilot-instructions.md +27 -4
- package/rules/.source/hippy/extend_views/CoverFlowHorizontalView.java +203 -0
- package/rules/.source/hippy/extend_views/CoverFlowVerticalView.java +203 -0
- package/rules/.source/hippy/extend_views/CoverFlowViewController.java +195 -0
- package/rules/.source/hippy/extend_views/EngineRootView.java +125 -0
- package/rules/.source/hippy/extend_views/ExtendTag.java +83 -0
- package/rules/.source/hippy/extend_views/FocusSearchHelper.java +124 -0
- package/rules/.source/hippy/extend_views/IRecyclerItemView.java +12 -0
- package/rules/.source/hippy/extend_views/JSEventHandleView.java +5 -0
- package/rules/.source/hippy/extend_views/MarqueeRelayManager.java +133 -0
- package/rules/.source/hippy/extend_views/MarqueeRelayTextView.java +211 -0
- package/rules/.source/hippy/extend_views/ProgressBarView.java +83 -0
- package/rules/.source/hippy/extend_views/ProgressBarViewController.java +145 -0
- package/rules/.source/hippy/extend_views/SeekBarView.java +104 -0
- package/rules/.source/hippy/extend_views/SeekBarViewController.java +218 -0
- package/rules/.source/hippy/extend_views/StateImageView.java +149 -0
- package/rules/.source/hippy/extend_views/StateImageViewController.java +34 -0
- package/rules/.source/hippy/extend_views/TVButtonView.java +314 -0
- package/rules/.source/hippy/extend_views/TVButtonViewController.java +89 -0
- package/rules/.source/hippy/extend_views/TVTextView.java +684 -0
- package/rules/.source/hippy/extend_views/TVViewActor.java +811 -0
- package/rules/.source/hippy/extend_views/TVViewActorHost.java +6 -0
- package/rules/.source/hippy/extend_views/TVViewActor/346/216/245/345/205/245.md +66 -0
- package/rules/.source/hippy/extend_views/TemplateUtil.java +336 -0
- package/rules/.source/hippy/extend_views/TextButtonNode.java +47 -0
- package/rules/.source/hippy/extend_views/TextViewController.java +377 -0
- package/rules/.source/hippy/extend_views/fastlist/CenterFlyInAnimator.java +96 -0
- package/rules/.source/hippy/extend_views/fastlist/ChildOnScreenScroller.java +548 -0
- package/rules/.source/hippy/extend_views/fastlist/ClonedViewTag.java +17 -0
- package/rules/.source/hippy/extend_views/fastlist/EventDeliverer.java +55 -0
- package/rules/.source/hippy/extend_views/fastlist/FastAdapter.java +4683 -0
- package/rules/.source/hippy/extend_views/fastlist/FastAdapterUtil.java +982 -0
- package/rules/.source/hippy/extend_views/fastlist/FastFlexNode.java +48 -0
- package/rules/.source/hippy/extend_views/fastlist/FastFlexView.java +873 -0
- package/rules/.source/hippy/extend_views/fastlist/FastFlexViewController.java +130 -0
- package/rules/.source/hippy/extend_views/fastlist/FastItemNode.java +67 -0
- package/rules/.source/hippy/extend_views/fastlist/FastItemView.java +306 -0
- package/rules/.source/hippy/extend_views/fastlist/FastItemViewController.java +106 -0
- package/rules/.source/hippy/extend_views/fastlist/FastListModule.java +95 -0
- package/rules/.source/hippy/extend_views/fastlist/FastListNode.java +90 -0
- package/rules/.source/hippy/extend_views/fastlist/FastListView.java +2466 -0
- package/rules/.source/hippy/extend_views/fastlist/FastListViewController.java +1038 -0
- package/rules/.source/hippy/extend_views/fastlist/FastListView/346/270/262/346/237/223/346/265/201/347/250/213/345/233/276.graffle +0 -0
- package/rules/.source/hippy/extend_views/fastlist/FastPendingView.java +47 -0
- package/rules/.source/hippy/extend_views/fastlist/ItemDecorations.java +71 -0
- package/rules/.source/hippy/extend_views/fastlist/ItemStoreNode.java +64 -0
- package/rules/.source/hippy/extend_views/fastlist/ItemStoreView.java +13 -0
- package/rules/.source/hippy/extend_views/fastlist/ItemStoreViewController.java +45 -0
- package/rules/.source/hippy/extend_views/fastlist/ListItemHolder.java +7 -0
- package/rules/.source/hippy/extend_views/fastlist/ListViewControlProp.java +41 -0
- package/rules/.source/hippy/extend_views/fastlist/MouseRecycleView.java +509 -0
- package/rules/.source/hippy/extend_views/fastlist/OnFastItemClickListener.java +12 -0
- package/rules/.source/hippy/extend_views/fastlist/OnFastItemFocusChangeListener.java +9 -0
- package/rules/.source/hippy/extend_views/fastlist/OnFastScrollStateChangedListener.java +7 -0
- package/rules/.source/hippy/extend_views/fastlist/PendingListNode.java +18 -0
- package/rules/.source/hippy/extend_views/fastlist/PendingViewController.java +13 -0
- package/rules/.source/hippy/extend_views/fastlist/PostHandlerView.java +6 -0
- package/rules/.source/hippy/extend_views/fastlist/PostTaskHolder.java +20 -0
- package/rules/.source/hippy/extend_views/fastlist/ReplaceChildController.java +105 -0
- package/rules/.source/hippy/extend_views/fastlist/ReplaceChildView.java +312 -0
- package/rules/.source/hippy/extend_views/fastlist/TVListView.java +3692 -0
- package/rules/.source/hippy/extend_views/fastlist/TemplateCodeParser.java +247 -0
- package/rules/.source/hippy/extend_views/fastlist/Utils.java +572 -0
- package/rules/.source/hippy/extend_views/fastlist/ViewTag.java +317 -0
- package/rules/.source/hippy/extend_views/fastlist/VirtualListView.java +8 -0
- package/rules/.source/hippy/extend_views/fastlist/diff/FastListDataBindingHelper.java +320 -0
- package/rules/.source/hippy/extend_views/fastlist/diff/KeyDiffHelper.java +289 -0
- package/rules/.source/hippy/extend_views/fastlist/diff/NoKeyDiffHelper.java +278 -0
- package/rules/.source/hippy/extend_views/tag/FontTag.java +53 -0
- package/rules/.source/hippy/extend_views/tag/HtmlTag.java +191 -0
- package/rules/.source/hippy/extend_views/tag/HtmlTagHandler.java +185 -0
- package/rules/.source/hippy/extend_views/tag/SpanTag.java +160 -0
- package/rules/.source/hippy/extend_views/tag/TextFontSpan.java +102 -0
- package/rules/.source/hippy/extend_views/waterfall/Chunk.java +10 -0
- package/rules/.source/hippy/extend_views/waterfall/ChunkGroup.java +5 -0
- package/rules/.source/hippy/extend_views/waterfall/Section.java +4 -0
- package/rules/.source/hippy/extend_views/waterfall/Tabs.java +5 -0
- package/rules/.source/hippy/extend_views/waterfall/WaterfallUtils.java +26 -0
- package/rules/.source/hippy/hippy_uimanager/ControllerHolder.java +30 -0
- package/rules/.source/hippy/hippy_uimanager/ControllerManager.java +651 -0
- package/rules/.source/hippy/hippy_uimanager/ControllerRegistry.java +102 -0
- package/rules/.source/hippy/hippy_uimanager/ControllerUpdateManger.java +252 -0
- package/rules/.source/hippy/hippy_uimanager/CustomControllerHelper.java +425 -0
- package/rules/.source/hippy/hippy_uimanager/DiffUtils.java +526 -0
- package/rules/.source/hippy/hippy_uimanager/ExtendViewGroup.java +36 -0
- package/rules/.source/hippy/hippy_uimanager/HippyCustomViewCreator.java +29 -0
- package/rules/.source/hippy/hippy_uimanager/HippyGroupController.java +83 -0
- package/rules/.source/hippy/hippy_uimanager/HippyViewBase.java +27 -0
- package/rules/.source/hippy/hippy_uimanager/HippyViewController.java +2189 -0
- package/rules/.source/hippy/hippy_uimanager/HippyViewEvent.java +52 -0
- package/rules/.source/hippy/hippy_uimanager/IHippyZIndexViewGroup.java +24 -0
- package/rules/.source/hippy/hippy_uimanager/InternalExtendViewUtil.java +395 -0
- package/rules/.source/hippy/hippy_uimanager/ListItemRenderNode.java +143 -0
- package/rules/.source/hippy/hippy_uimanager/ListViewRenderNode.java +44 -0
- package/rules/.source/hippy/hippy_uimanager/MatrixUtil.java +470 -0
- package/rules/.source/hippy/hippy_uimanager/NativeGestureDispatcher.java +349 -0
- package/rules/.source/hippy/hippy_uimanager/NativeGestureProcessor.java +188 -0
- package/rules/.source/hippy/hippy_uimanager/PullFooterRenderNode.java +43 -0
- package/rules/.source/hippy/hippy_uimanager/PullHeaderRenderNode.java +43 -0
- package/rules/.source/hippy/hippy_uimanager/RenderManager.java +304 -0
- package/rules/.source/hippy/hippy_uimanager/RenderNode.java +533 -0
- package/rules/.source/hippy/hippy_uimanager/StateView.java +17 -0
- package/rules/.source/hippy/hippy_uimanager/TransformUtil.java +125 -0
- package/rules/.source/hippy/hippy_uimanager/ViewGroupDrawingOrderHelper.java +108 -0
- package/rules/.source/hippy/hippy_uimanager/ViewStateProvider.java +10 -0
- package/rules/.source/hippy/hippy_views/audioview/AudioPlayManager.java +457 -0
- package/rules/.source/hippy/hippy_views/audioview/AudioView.java +225 -0
- package/rules/.source/hippy/hippy_views/audioview/AudioViewController.java +135 -0
- package/rules/.source/hippy/hippy_views/common/CommonBackgroundDrawable.java +58 -0
- package/rules/.source/hippy/hippy_views/common/CommonBorder.java +37 -0
- package/rules/.source/hippy/hippy_views/custom/HippyCustomPropsController.java +61 -0
- package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerListAdapter.java +399 -0
- package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerView.java +378 -0
- package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerViewController.java +187 -0
- package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerViewHolder.java +39 -0
- package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerViewWrapper.java +134 -0
- package/rules/.source/hippy/hippy_views/hippylist/NodePositionHelper.java +55 -0
- package/rules/.source/hippy/hippy_views/hippylist/PreloadHelper.java +54 -0
- package/rules/.source/hippy/hippy_views/hippylist/PullFooterEventHelper.java +61 -0
- package/rules/.source/hippy/hippy_views/hippylist/PullHeaderEventHelper.java +127 -0
- package/rules/.source/hippy/hippy_views/hippylist/RecyclerViewEventHelper.java +394 -0
- package/rules/.source/hippy/hippy_views/image/HippyContentDrawable.java +113 -0
- package/rules/.source/hippy/hippy_views/image/HippyImageView.java +1608 -0
- package/rules/.source/hippy/hippy_views/image/HippyImageViewController.java +382 -0
- package/rules/.source/hippy/hippy_views/image/IImageStateListener.java +7 -0
- package/rules/.source/hippy/hippy_views/list/ChildOnScreenScroller.java +255 -0
- package/rules/.source/hippy/hippy_views/list/HippyListAdapter.java +647 -0
- package/rules/.source/hippy/hippy_views/list/HippyListItemView.java +162 -0
- package/rules/.source/hippy/hippy_views/list/HippyListItemViewController.java +45 -0
- package/rules/.source/hippy/hippy_views/list/HippyListView.java +915 -0
- package/rules/.source/hippy/hippy_views/list/HippyListViewController.java +622 -0
- package/rules/.source/hippy/hippy_views/list/HippyRecycler.java +31 -0
- package/rules/.source/hippy/hippy_views/list/IRecycleItemTypeChange.java +23 -0
- package/rules/.source/hippy/hippy_views/list/ItemDecorations.java +70 -0
- package/rules/.source/hippy/hippy_views/list/NegativeLongKeyFlinger.java +156 -0
- package/rules/.source/hippy/hippy_views/list/NodeHolder.java +34 -0
- package/rules/.source/hippy/hippy_views/list/RecycleViewFlinger.java +126 -0
- package/rules/.source/hippy/hippy_views/list/TVRecyclerView.java +2070 -0
- package/rules/.source/hippy/hippy_views/list/TVSingleLineListView.java +15 -0
- package/rules/.source/hippy/hippy_views/modal/HippyModalHostManager.java +102 -0
- package/rules/.source/hippy/hippy_views/modal/HippyModalHostView.java +597 -0
- package/rules/.source/hippy/hippy_views/modal/ModalHostHelper.java +46 -0
- package/rules/.source/hippy/hippy_views/modal/ModalStyleNode.java +34 -0
- package/rules/.source/hippy/hippy_views/modal/RequestCloseEvent.java +32 -0
- package/rules/.source/hippy/hippy_views/modal/ShowEvent.java +31 -0
- package/rules/.source/hippy/hippy_views/navigator/Navigator.java +126 -0
- package/rules/.source/hippy/hippy_views/navigator/NavigatorController.java +120 -0
- package/rules/.source/hippy/hippy_views/refresh/HippyPullFooterView.java +47 -0
- package/rules/.source/hippy/hippy_views/refresh/HippyPullFooterViewController.java +65 -0
- package/rules/.source/hippy/hippy_views/refresh/HippyPullHeaderView.java +39 -0
- package/rules/.source/hippy/hippy_views/refresh/HippyPullHeaderViewController.java +104 -0
- package/rules/.source/hippy/hippy_views/refresh/RefreshWrapper.java +237 -0
- package/rules/.source/hippy/hippy_views/refresh/RefreshWrapperController.java +62 -0
- package/rules/.source/hippy/hippy_views/refresh/RefreshWrapperItemController.java +39 -0
- package/rules/.source/hippy/hippy_views/refresh/RefreshWrapperItemView.java +26 -0
- package/rules/.source/hippy/hippy_views/scroll/HippyHorizontalScrollView.java +500 -0
- package/rules/.source/hippy/hippy_views/scroll/HippyOnScrollHelper.java +39 -0
- package/rules/.source/hippy/hippy_views/scroll/HippyScrollView.java +46 -0
- package/rules/.source/hippy/hippy_views/scroll/HippyScrollViewController.java +178 -0
- package/rules/.source/hippy/hippy_views/scroll/HippyScrollViewEventHelper.java +92 -0
- package/rules/.source/hippy/hippy_views/scroll/HippyVerticalScrollView.java +522 -0
- package/rules/.source/hippy/hippy_views/text/HippyTextView.java +512 -0
- package/rules/.source/hippy/hippy_views/text/HippyTextViewController.java +77 -0
- package/rules/.source/hippy/hippy_views/textinput/HippyTextInput.java +668 -0
- package/rules/.source/hippy/hippy_views/textinput/HippyTextInputController.java +528 -0
- package/rules/.source/hippy/hippy_views/textinput/TextInputNode.java +115 -0
- package/rules/.source/hippy/hippy_views/videoview/APEZProvider.java +287 -0
- package/rules/.source/hippy/hippy_views/videoview/APKExpansionSupport.java +82 -0
- package/rules/.source/hippy/hippy_views/videoview/PivotPoint.java +13 -0
- package/rules/.source/hippy/hippy_views/videoview/ScalableType.java +34 -0
- package/rules/.source/hippy/hippy_views/videoview/ScalableVideoView.java +265 -0
- package/rules/.source/hippy/hippy_views/videoview/ScaleManager.java +191 -0
- package/rules/.source/hippy/hippy_views/videoview/Size.java +19 -0
- package/rules/.source/hippy/hippy_views/videoview/VideoHippyView.java +917 -0
- package/rules/.source/hippy/hippy_views/videoview/VideoHippyViewController.java +236 -0
- package/rules/.source/hippy/hippy_views/videoview/ZipResourceFile.java +427 -0
- package/rules/.source/hippy/hippy_views/view/CardRootView.java +28 -0
- package/rules/.source/hippy/hippy_views/view/CustomLayoutView.java +10 -0
- package/rules/.source/hippy/hippy_views/view/CustomNodeView.java +5 -0
- package/rules/.source/hippy/hippy_views/view/DialogViewGroup.java +113 -0
- package/rules/.source/hippy/hippy_views/view/HippyViewGroup.java +2042 -0
- package/rules/.source/hippy/hippy_views/view/HippyViewGroupController.java +583 -0
- package/rules/.source/hippy/hippy_views/view/WindowRoot.java +5 -0
- package/rules/.source/hippy/hippy_views/viewpager/HippyViewPager.java +308 -0
- package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerAdapter.java +148 -0
- package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerController.java +246 -0
- package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerItem.java +27 -0
- package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerItemController.java +42 -0
- package/rules/.source/hippy/hippy_views/viewpager/ViewPagerPageChangeListener.java +114 -0
- package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageItemExposureEvent.java +40 -0
- package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageScrollEvent.java +43 -0
- package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageScrollStateChangedEvent.java +42 -0
- package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageSelectedEvent.java +42 -0
- package/rules/.source/hippy/hippy_views/webview/HippyWebView.java +160 -0
- package/rules/.source/hippy/hippy_views/webview/HippyWebViewBridge.java +20 -0
- package/rules/.source/hippy/hippy_views/webview/HippyWebViewController.java +103 -0
- package/rules/.source/hippy/hippy_views/webview/HippyWebViewInner.java +77 -0
- package/rules/.windsurfrules +27 -4
- package/rules/AGENTS.md +27 -4
- package/rules/CLAUDE.md +27 -3
- package/rules/GEMINI.md +25 -3
|
@@ -0,0 +1,917 @@
|
|
|
1
|
+
package com.tencent.mtt.hippy.views.videoview;
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint;
|
|
4
|
+
import android.annotation.TargetApi;
|
|
5
|
+
import android.app.Activity;
|
|
6
|
+
import android.content.Context;
|
|
7
|
+
import android.content.res.AssetFileDescriptor;
|
|
8
|
+
import android.graphics.Matrix;
|
|
9
|
+
import android.media.MediaPlayer;
|
|
10
|
+
import android.media.TimedMetaData;
|
|
11
|
+
import android.net.Uri;
|
|
12
|
+
import android.os.Build;
|
|
13
|
+
import android.os.Handler;
|
|
14
|
+
import android.util.Log;
|
|
15
|
+
import android.view.MotionEvent;
|
|
16
|
+
import android.view.View;
|
|
17
|
+
import android.view.Window;
|
|
18
|
+
import android.widget.MediaController;
|
|
19
|
+
|
|
20
|
+
import com.tencent.mtt.hippy.HippyEngineContext;
|
|
21
|
+
import com.tencent.mtt.hippy.HippyInstanceContext;
|
|
22
|
+
import com.tencent.mtt.hippy.common.HippyArray;
|
|
23
|
+
import com.tencent.mtt.hippy.common.HippyMap;
|
|
24
|
+
import com.tencent.mtt.hippy.modules.javascriptmodules.EventDispatcher;
|
|
25
|
+
import com.tencent.mtt.hippy.modules.nativemodules.network.CookieManagerAdapter;
|
|
26
|
+
import com.tencent.mtt.hippy.uimanager.HippyViewBase;
|
|
27
|
+
import com.tencent.mtt.hippy.uimanager.NativeGestureDispatcher;
|
|
28
|
+
|
|
29
|
+
import java.io.IOException;
|
|
30
|
+
import java.math.BigDecimal;
|
|
31
|
+
import java.nio.charset.Charset;
|
|
32
|
+
import java.util.HashMap;
|
|
33
|
+
import java.util.Iterator;
|
|
34
|
+
import java.util.Map;
|
|
35
|
+
import java.util.Set;
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
public class VideoHippyView extends ScalableVideoView
|
|
39
|
+
implements HippyViewBase, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener,
|
|
40
|
+
MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnInfoListener, MediaController.MediaPlayerControl
|
|
41
|
+
{
|
|
42
|
+
|
|
43
|
+
@Override
|
|
44
|
+
public NativeGestureDispatcher getGestureDispatcher()
|
|
45
|
+
{
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@Override
|
|
50
|
+
public void setGestureDispatcher(NativeGestureDispatcher dispatcher)
|
|
51
|
+
{
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public void setControlVisible(boolean show) {
|
|
56
|
+
if(mediaController != null){
|
|
57
|
+
if (show) {
|
|
58
|
+
mediaController.show();
|
|
59
|
+
} else {
|
|
60
|
+
mediaController.hide();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//通知播放事件的回调。
|
|
66
|
+
public enum Events
|
|
67
|
+
{
|
|
68
|
+
EVENT_LOAD_START("onVideoLoadStart"),
|
|
69
|
+
EVENT_LOAD("onVideoLoad"),
|
|
70
|
+
EVENT_ERROR("onVideoError"),
|
|
71
|
+
EVENT_PROGRESS("onVideoProgress"),
|
|
72
|
+
EVENT_TIMED_METADATA("onTimedMetadata"),
|
|
73
|
+
EVENT_SEEK("onVideoSeek"),
|
|
74
|
+
EVENT_PLAY("onVideoPlay"),
|
|
75
|
+
EVENT_PAUSE("onVideoPause"),
|
|
76
|
+
EVENT_END("onVideoEnd"),
|
|
77
|
+
EVENT_STALLED("onPlaybackStalled"),
|
|
78
|
+
EVENT_RESUME("onPlaybackResume"),
|
|
79
|
+
EVENT_READY_FOR_DISPLAY("onReadyForDisplay"),
|
|
80
|
+
EVENT_FULLSCREEN_WILL_PRESENT("onVideoFullscreenPlayerWillPresent"),
|
|
81
|
+
EVENT_FULLSCREEN_DID_PRESENT("onVideoFullscreenPlayerDidPresent"),
|
|
82
|
+
EVENT_FULLSCREEN_WILL_DISMISS("onVideoFullscreenPlayerWillDismiss"),
|
|
83
|
+
EVENT_FULLSCREEN_DID_DISMISS("onVideoFullscreenPlayerDidDismiss");
|
|
84
|
+
|
|
85
|
+
private final String mName;
|
|
86
|
+
|
|
87
|
+
Events(final String name)
|
|
88
|
+
{
|
|
89
|
+
mName = name;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@Override
|
|
93
|
+
public String toString()
|
|
94
|
+
{
|
|
95
|
+
return mName;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
public static final String EVENT_PROP_FAST_FORWARD = "canPlayFastForward";
|
|
101
|
+
public static final String EVENT_PROP_SLOW_FORWARD = "canPlaySlowForward";
|
|
102
|
+
public static final String EVENT_PROP_SLOW_REVERSE = "canPlaySlowReverse";
|
|
103
|
+
public static final String EVENT_PROP_REVERSE = "canPlayReverse";
|
|
104
|
+
public static final String EVENT_PROP_STEP_FORWARD = "canStepForward";
|
|
105
|
+
public static final String EVENT_PROP_STEP_BACKWARD = "canStepBackward";
|
|
106
|
+
|
|
107
|
+
public static final String EVENT_PROP_DURATION = "duration";
|
|
108
|
+
public static final String EVENT_PROP_PLAYABLE_DURATION = "playableDuration";
|
|
109
|
+
public static final String EVENT_PROP_SEEKABLE_DURATION = "seekableDuration";
|
|
110
|
+
public static final String EVENT_PROP_CURRENT_TIME = "currentTime";
|
|
111
|
+
public static final String EVENT_PROP_SEEK_TIME = "seekTime";
|
|
112
|
+
public static final String EVENT_PROP_NATURALSIZE = "naturalSize";
|
|
113
|
+
public static final String EVENT_PROP_WIDTH = "width";
|
|
114
|
+
public static final String EVENT_PROP_HEIGHT = "height";
|
|
115
|
+
public static final String EVENT_PROP_ORIENTATION = "orientation";
|
|
116
|
+
public static final String EVENT_PROP_METADATA = "metadata";
|
|
117
|
+
public static final String EVENT_PROP_TARGET = "target";
|
|
118
|
+
public static final String EVENT_PROP_METADATA_IDENTIFIER = "identifier";
|
|
119
|
+
public static final String EVENT_PROP_METADATA_VALUE = "value";
|
|
120
|
+
|
|
121
|
+
public static final String EVENT_PROP_ERROR = "error";
|
|
122
|
+
public static final String EVENT_PROP_WHAT = "what";
|
|
123
|
+
public static final String EVENT_PROP_EXTRA = "extra";
|
|
124
|
+
|
|
125
|
+
private HippyEngineContext mHippyContext;
|
|
126
|
+
private final Context mAppContext;
|
|
127
|
+
private final EventDispatcher mEventEmitter;
|
|
128
|
+
|
|
129
|
+
private final Handler mProgressUpdateHandler = new Handler();
|
|
130
|
+
private Runnable mProgressUpdateRunnable = null;
|
|
131
|
+
private final Handler videoControlHandler = new Handler();
|
|
132
|
+
private MediaController mediaController;
|
|
133
|
+
|
|
134
|
+
private String mSrcUriString = null;
|
|
135
|
+
private String mSrcType = "mp4";
|
|
136
|
+
private HippyMap mRequestHeaders = null;
|
|
137
|
+
private boolean mSrcIsNetwork = false;
|
|
138
|
+
private boolean mSrcIsAsset = false;
|
|
139
|
+
private ScalableType mResizeMode = ScalableType.LEFT_TOP;
|
|
140
|
+
private boolean mRepeat = false;
|
|
141
|
+
private boolean mPaused = false;
|
|
142
|
+
private boolean mMuted = false;
|
|
143
|
+
private float mVolume = 1.0f;
|
|
144
|
+
private float mStereoPan = 0.0f;
|
|
145
|
+
private float mProgressUpdateInterval = 250.0f;
|
|
146
|
+
private float mRate = 1.0f;
|
|
147
|
+
private float mActiveRate = 1.0f;
|
|
148
|
+
private long mSeekTime = 0;
|
|
149
|
+
private boolean mPlayInBackground = false;
|
|
150
|
+
private final boolean mBackgroundPaused = false;
|
|
151
|
+
private boolean mIsFullscreen = false;
|
|
152
|
+
|
|
153
|
+
private int mMainVer = 0;
|
|
154
|
+
private int mPatchVer = 0;
|
|
155
|
+
|
|
156
|
+
private boolean mMediaPlayerValid = false; // True if mMediaPlayer is in prepared, started, paused or completed state.
|
|
157
|
+
|
|
158
|
+
private int mVideoDuration = 0;
|
|
159
|
+
private int mVideoBufferedDuration = 0;
|
|
160
|
+
private boolean isCompleted = false;
|
|
161
|
+
private boolean mUseNativeControls = false;
|
|
162
|
+
|
|
163
|
+
public VideoHippyView(Context context)
|
|
164
|
+
{
|
|
165
|
+
super(context);
|
|
166
|
+
mHippyContext = ((HippyInstanceContext) context).getEngineContext();
|
|
167
|
+
|
|
168
|
+
mEventEmitter = mHippyContext.getModuleManager().getJavaScriptModule(EventDispatcher.class);
|
|
169
|
+
// themedReactContext.addLifecycleEventListener(this);
|
|
170
|
+
mAppContext =context;
|
|
171
|
+
initializeMediaPlayerIfNeeded();
|
|
172
|
+
setSurfaceTextureListener(this);
|
|
173
|
+
|
|
174
|
+
mProgressUpdateRunnable = new Runnable()
|
|
175
|
+
{
|
|
176
|
+
@Override
|
|
177
|
+
public void run()
|
|
178
|
+
{
|
|
179
|
+
|
|
180
|
+
if (mMediaPlayerValid && !isCompleted && !mPaused && !mBackgroundPaused)
|
|
181
|
+
{
|
|
182
|
+
HippyMap event = new HippyMap();
|
|
183
|
+
event.pushDouble(EVENT_PROP_CURRENT_TIME, mMediaPlayer.getCurrentPosition() / 1000.0);
|
|
184
|
+
event.pushDouble(EVENT_PROP_PLAYABLE_DURATION, mVideoBufferedDuration / 1000.0); //TODO:mBufferUpdateRunnable
|
|
185
|
+
event.pushDouble(EVENT_PROP_SEEKABLE_DURATION, mVideoDuration / 1000.0);
|
|
186
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_PROGRESS.toString(), event);
|
|
187
|
+
|
|
188
|
+
// Check for update after an interval
|
|
189
|
+
mProgressUpdateHandler.postDelayed(mProgressUpdateRunnable, 1000);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@Override
|
|
196
|
+
public boolean onTouchEvent(MotionEvent event)
|
|
197
|
+
{
|
|
198
|
+
if (mUseNativeControls)
|
|
199
|
+
{
|
|
200
|
+
initializeMediaControllerIfNeeded();
|
|
201
|
+
mediaController.show();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return super.onTouchEvent(event);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
@Override
|
|
208
|
+
@SuppressLint("DrawAllocation")
|
|
209
|
+
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
|
|
210
|
+
{
|
|
211
|
+
super.onLayout(changed, left, top, right, bottom);
|
|
212
|
+
|
|
213
|
+
if (!changed || !mMediaPlayerValid)
|
|
214
|
+
{
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
int videoWidth = getVideoWidth();
|
|
219
|
+
int videoHeight = getVideoHeight();
|
|
220
|
+
|
|
221
|
+
if (videoWidth == 0 || videoHeight == 0)
|
|
222
|
+
{
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
Size viewSize = new Size(getWidth(), getHeight());
|
|
227
|
+
Size videoSize = new Size(videoWidth, videoHeight);
|
|
228
|
+
ScaleManager scaleManager = new ScaleManager(viewSize, videoSize);
|
|
229
|
+
Matrix matrix = scaleManager.getScaleMatrix(mScalableType);
|
|
230
|
+
if (matrix != null)
|
|
231
|
+
{
|
|
232
|
+
setTransform(matrix);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private void initializeMediaPlayerIfNeeded()
|
|
237
|
+
{
|
|
238
|
+
if (mMediaPlayer == null)
|
|
239
|
+
{
|
|
240
|
+
mMediaPlayerValid = false;
|
|
241
|
+
mMediaPlayer = new MediaPlayer();
|
|
242
|
+
mMediaPlayer.setScreenOnWhilePlaying(true);
|
|
243
|
+
mMediaPlayer.setOnVideoSizeChangedListener(this);
|
|
244
|
+
mMediaPlayer.setOnErrorListener(this);
|
|
245
|
+
mMediaPlayer.setOnPreparedListener(this);
|
|
246
|
+
mMediaPlayer.setOnBufferingUpdateListener(this);
|
|
247
|
+
mMediaPlayer.setOnSeekCompleteListener(this);
|
|
248
|
+
mMediaPlayer.setOnCompletionListener(this);
|
|
249
|
+
mMediaPlayer.setOnInfoListener(this);
|
|
250
|
+
if (Build.VERSION.SDK_INT >= 23)
|
|
251
|
+
{
|
|
252
|
+
mMediaPlayer.setOnTimedMetaDataAvailableListener(new TimedMetaDataAvailableListener());
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private void initializeMediaControllerIfNeeded()
|
|
258
|
+
{
|
|
259
|
+
if (mediaController == null)
|
|
260
|
+
{
|
|
261
|
+
mediaController = new MediaController(this.getContext());
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
public void cleanupMediaPlayerResources()
|
|
266
|
+
{
|
|
267
|
+
if (mediaController != null)
|
|
268
|
+
{
|
|
269
|
+
mediaController.hide();
|
|
270
|
+
}
|
|
271
|
+
if (mMediaPlayer != null)
|
|
272
|
+
{
|
|
273
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
|
274
|
+
{
|
|
275
|
+
mMediaPlayer.setOnTimedMetaDataAvailableListener(null);
|
|
276
|
+
}
|
|
277
|
+
mMediaPlayerValid = false;
|
|
278
|
+
release();
|
|
279
|
+
}
|
|
280
|
+
if (mIsFullscreen)
|
|
281
|
+
{
|
|
282
|
+
setFullscreen(false);
|
|
283
|
+
}
|
|
284
|
+
mHippyContext = null;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
public void setSrc(final String uriString, final String type, final boolean isNetwork, final boolean isAsset, final HippyMap requestHeaders)
|
|
288
|
+
{
|
|
289
|
+
setSrc(uriString, type, isNetwork, isAsset, requestHeaders, 0, 0);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
public void setSrc(final String uriString, final String type, final boolean isNetwork, final boolean isAsset, final HippyMap requestHeaders,
|
|
293
|
+
final int expansionMainVersion, final int expansionPatchVersion)
|
|
294
|
+
{
|
|
295
|
+
|
|
296
|
+
mSrcUriString = uriString;
|
|
297
|
+
mSrcType = type;
|
|
298
|
+
mSrcIsNetwork = isNetwork;
|
|
299
|
+
mSrcIsAsset = isAsset;
|
|
300
|
+
mRequestHeaders = requestHeaders;
|
|
301
|
+
mMainVer = expansionMainVersion;
|
|
302
|
+
mPatchVer = expansionPatchVersion;
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
mMediaPlayerValid = false;
|
|
306
|
+
mVideoDuration = 0;
|
|
307
|
+
mVideoBufferedDuration = 0;
|
|
308
|
+
|
|
309
|
+
initializeMediaPlayerIfNeeded();
|
|
310
|
+
mMediaPlayer.reset();
|
|
311
|
+
|
|
312
|
+
try
|
|
313
|
+
{
|
|
314
|
+
if (isNetwork)
|
|
315
|
+
{
|
|
316
|
+
// Use the shared CookieManager to access the cookies
|
|
317
|
+
// set by WebViews inside the same app
|
|
318
|
+
|
|
319
|
+
Uri parsedUrl = Uri.parse(uriString);
|
|
320
|
+
Uri.Builder builtUrl = parsedUrl.buildUpon();
|
|
321
|
+
|
|
322
|
+
String cookie = CookieManagerAdapter.get().getCookie(builtUrl.build().toString());
|
|
323
|
+
|
|
324
|
+
Map<String, String> headers = new HashMap<String, String>();
|
|
325
|
+
|
|
326
|
+
if (cookie != null)
|
|
327
|
+
{
|
|
328
|
+
headers.put("Cookie", cookie);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (mRequestHeaders != null)
|
|
332
|
+
{
|
|
333
|
+
headers.putAll(toStringMap(mRequestHeaders));
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/*
|
|
337
|
+
* According to
|
|
338
|
+
* https://github.com/react-native-community/react-native-video/pull/537
|
|
339
|
+
* there is an issue with this where it can cause a IOException.
|
|
340
|
+
* TODO: diagnose this exception and fix it
|
|
341
|
+
*/
|
|
342
|
+
setDataSource(mAppContext, parsedUrl, headers);
|
|
343
|
+
}
|
|
344
|
+
else if (isAsset)
|
|
345
|
+
{
|
|
346
|
+
if (uriString.startsWith("content://"))
|
|
347
|
+
{
|
|
348
|
+
Uri parsedUrl = Uri.parse(uriString);
|
|
349
|
+
setDataSource(mAppContext, parsedUrl);
|
|
350
|
+
}
|
|
351
|
+
else
|
|
352
|
+
{
|
|
353
|
+
setDataSource(uriString);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
else
|
|
357
|
+
{
|
|
358
|
+
ZipResourceFile expansionFile = null;
|
|
359
|
+
AssetFileDescriptor fd = null;
|
|
360
|
+
if (mMainVer > 0)
|
|
361
|
+
{
|
|
362
|
+
try
|
|
363
|
+
{
|
|
364
|
+
expansionFile = APKExpansionSupport.getAPKExpansionZipFile(mAppContext, mMainVer, mPatchVer);
|
|
365
|
+
fd = expansionFile.getAssetFileDescriptor(uriString.replace(".mp4", "") + ".mp4");
|
|
366
|
+
}
|
|
367
|
+
catch (IOException e)
|
|
368
|
+
{
|
|
369
|
+
e.printStackTrace();
|
|
370
|
+
}
|
|
371
|
+
catch (NullPointerException e)
|
|
372
|
+
{
|
|
373
|
+
e.printStackTrace();
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (fd == null)
|
|
377
|
+
{
|
|
378
|
+
int identifier = mAppContext.getResources().getIdentifier(uriString, "drawable", mAppContext.getPackageName());
|
|
379
|
+
if (identifier == 0)
|
|
380
|
+
{
|
|
381
|
+
identifier = mAppContext.getResources().getIdentifier(uriString, "raw", mAppContext.getPackageName());
|
|
382
|
+
}
|
|
383
|
+
setRawData(identifier);
|
|
384
|
+
}
|
|
385
|
+
else
|
|
386
|
+
{
|
|
387
|
+
setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
catch (Exception e)
|
|
392
|
+
{
|
|
393
|
+
e.printStackTrace();
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
HippyMap src = new HippyMap();
|
|
398
|
+
|
|
399
|
+
HippyMap wRequestHeaders = new HippyMap();
|
|
400
|
+
wRequestHeaders.pushAll(mRequestHeaders);
|
|
401
|
+
|
|
402
|
+
src.pushString(VideoHippyViewController.PROP_SRC_URI, uriString);
|
|
403
|
+
src.pushString(VideoHippyViewController.PROP_SRC_TYPE, type);
|
|
404
|
+
src.pushMap(VideoHippyViewController.PROP_SRC_HEADERS, wRequestHeaders);
|
|
405
|
+
src.pushBoolean(VideoHippyViewController.PROP_SRC_IS_NETWORK, isNetwork);
|
|
406
|
+
if (mMainVer > 0)
|
|
407
|
+
{
|
|
408
|
+
src.pushInt(VideoHippyViewController.PROP_SRC_MAINVER, mMainVer);
|
|
409
|
+
if (mPatchVer > 0)
|
|
410
|
+
{
|
|
411
|
+
src.pushInt(VideoHippyViewController.PROP_SRC_PATCHVER, mPatchVer);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
HippyMap event = new HippyMap();
|
|
415
|
+
event.pushMap(VideoHippyViewController.PROP_SRC, src);
|
|
416
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_LOAD_START.toString(), event);
|
|
417
|
+
isCompleted = false;
|
|
418
|
+
|
|
419
|
+
try
|
|
420
|
+
{
|
|
421
|
+
prepareAsync(this);
|
|
422
|
+
}
|
|
423
|
+
catch (Exception e)
|
|
424
|
+
{
|
|
425
|
+
e.printStackTrace();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
public void setResizeModeModifier(final ScalableType resizeMode)
|
|
430
|
+
{
|
|
431
|
+
mResizeMode = resizeMode;
|
|
432
|
+
|
|
433
|
+
if (mMediaPlayerValid)
|
|
434
|
+
{
|
|
435
|
+
setScalableType(resizeMode);
|
|
436
|
+
invalidate();
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
public void setRepeatModifier(final boolean repeat)
|
|
441
|
+
{
|
|
442
|
+
|
|
443
|
+
mRepeat = repeat;
|
|
444
|
+
|
|
445
|
+
if (mMediaPlayerValid)
|
|
446
|
+
{
|
|
447
|
+
setLooping(repeat);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
public void setPausedModifier(final boolean paused)
|
|
452
|
+
{
|
|
453
|
+
mPaused = paused;
|
|
454
|
+
|
|
455
|
+
if (!mMediaPlayerValid)
|
|
456
|
+
{
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
if (mPaused)
|
|
461
|
+
{
|
|
462
|
+
if (mMediaPlayer.isPlaying())
|
|
463
|
+
{
|
|
464
|
+
pause();
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
else
|
|
468
|
+
{
|
|
469
|
+
if (!mMediaPlayer.isPlaying())
|
|
470
|
+
{
|
|
471
|
+
start();
|
|
472
|
+
// Setting the rate unpauses, so we have to wait for an unpause
|
|
473
|
+
if (mRate != mActiveRate)
|
|
474
|
+
{
|
|
475
|
+
setRateModifier(mRate);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Also Start the Progress Update Handler
|
|
479
|
+
mProgressUpdateHandler.post(mProgressUpdateRunnable);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
setKeepScreenOn(!mPaused);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// reduces the volume based on stereoPan
|
|
486
|
+
private float calulateRelativeVolume()
|
|
487
|
+
{
|
|
488
|
+
float relativeVolume = (mVolume * (1 - Math.abs(mStereoPan)));
|
|
489
|
+
// only one decimal allowed
|
|
490
|
+
BigDecimal roundRelativeVolume = new BigDecimal(relativeVolume).setScale(1, BigDecimal.ROUND_HALF_UP);
|
|
491
|
+
return roundRelativeVolume.floatValue();
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
public void setMutedModifier(final boolean muted)
|
|
495
|
+
{
|
|
496
|
+
mMuted = muted;
|
|
497
|
+
|
|
498
|
+
if (!mMediaPlayerValid)
|
|
499
|
+
{
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
if (mMuted)
|
|
504
|
+
{
|
|
505
|
+
setVolume(0, 0);
|
|
506
|
+
}
|
|
507
|
+
else if (mStereoPan < 0)
|
|
508
|
+
{
|
|
509
|
+
// louder on the left channel
|
|
510
|
+
setVolume(mVolume, calulateRelativeVolume());
|
|
511
|
+
}
|
|
512
|
+
else if (mStereoPan > 0)
|
|
513
|
+
{
|
|
514
|
+
// louder on the right channel
|
|
515
|
+
setVolume(calulateRelativeVolume(), mVolume);
|
|
516
|
+
}
|
|
517
|
+
else
|
|
518
|
+
{
|
|
519
|
+
// same volume on both channels
|
|
520
|
+
setVolume(mVolume, mVolume);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
public void setVolumeModifier(final float volume)
|
|
525
|
+
{
|
|
526
|
+
mVolume = volume;
|
|
527
|
+
setMutedModifier(mMuted);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
public void setStereoPan(final float stereoPan)
|
|
531
|
+
{
|
|
532
|
+
mStereoPan = stereoPan;
|
|
533
|
+
setMutedModifier(mMuted);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
public void setProgressUpdateInterval(final float progressUpdateInterval)
|
|
537
|
+
{
|
|
538
|
+
mProgressUpdateInterval = progressUpdateInterval;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
public void setRateModifier(final float rate)
|
|
542
|
+
{
|
|
543
|
+
mRate = rate;
|
|
544
|
+
|
|
545
|
+
if (mMediaPlayerValid)
|
|
546
|
+
{
|
|
547
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
|
548
|
+
{
|
|
549
|
+
if (!mPaused)
|
|
550
|
+
{ // Applying the rate while paused will cause the video to start
|
|
551
|
+
/*
|
|
552
|
+
* Per https://stackoverflow.com/questions/39442522/setplaybackparams-causes-
|
|
553
|
+
* illegalstateexception
|
|
554
|
+
* Some devices throw an IllegalStateException if you set the rate without first
|
|
555
|
+
* calling reset()
|
|
556
|
+
* TODO: Call reset() then reinitialize the player
|
|
557
|
+
*/
|
|
558
|
+
try
|
|
559
|
+
{
|
|
560
|
+
mMediaPlayer.setPlaybackParams(mMediaPlayer.getPlaybackParams().setSpeed(rate));
|
|
561
|
+
mActiveRate = rate;
|
|
562
|
+
}
|
|
563
|
+
catch (Exception e)
|
|
564
|
+
{
|
|
565
|
+
Log.e(VideoHippyViewController.CLASS_NAME, "Unable to set rate, unsupported on this device");
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
else
|
|
570
|
+
{
|
|
571
|
+
Log.e(VideoHippyViewController.CLASS_NAME, "Setting playback rate is not yet supported on Android versions below 6.0");
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
public void setFullscreen(boolean isFullscreen)
|
|
577
|
+
{
|
|
578
|
+
if (isFullscreen == mIsFullscreen)
|
|
579
|
+
{
|
|
580
|
+
return; // Avoid generating events when nothing is changing
|
|
581
|
+
}
|
|
582
|
+
mIsFullscreen = isFullscreen;
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
if (!(mAppContext instanceof Activity ) || mAppContext == null )
|
|
586
|
+
{
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
Activity activity =(Activity)mAppContext;
|
|
590
|
+
Window window = activity.getWindow();
|
|
591
|
+
View decorView = window.getDecorView();
|
|
592
|
+
int uiOptions;
|
|
593
|
+
if (mIsFullscreen)
|
|
594
|
+
{
|
|
595
|
+
if (Build.VERSION.SDK_INT >= 19)
|
|
596
|
+
{ // 4.4+
|
|
597
|
+
uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY | SYSTEM_UI_FLAG_FULLSCREEN;
|
|
598
|
+
}
|
|
599
|
+
else
|
|
600
|
+
{
|
|
601
|
+
uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_FULLSCREEN;
|
|
602
|
+
}
|
|
603
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_FULLSCREEN_WILL_PRESENT.toString(), null);
|
|
604
|
+
decorView.setSystemUiVisibility(uiOptions);
|
|
605
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_FULLSCREEN_DID_PRESENT.toString(), null);
|
|
606
|
+
}
|
|
607
|
+
else
|
|
608
|
+
{
|
|
609
|
+
uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
|
|
610
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_FULLSCREEN_WILL_DISMISS.toString(), null);
|
|
611
|
+
decorView.setSystemUiVisibility(uiOptions);
|
|
612
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_FULLSCREEN_DID_DISMISS.toString(), null);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
public void applyModifiers(boolean paused)
|
|
617
|
+
{
|
|
618
|
+
setResizeModeModifier(mResizeMode);
|
|
619
|
+
setRepeatModifier(mRepeat);
|
|
620
|
+
setPausedModifier(paused);
|
|
621
|
+
setMutedModifier(mMuted);
|
|
622
|
+
setProgressUpdateInterval(mProgressUpdateInterval);
|
|
623
|
+
setRateModifier(mRate);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
public void setPlayInBackground(final boolean playInBackground)
|
|
627
|
+
{
|
|
628
|
+
|
|
629
|
+
mPlayInBackground = playInBackground;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
public void setControls(boolean controls)
|
|
633
|
+
{
|
|
634
|
+
this.mUseNativeControls = controls;
|
|
635
|
+
}
|
|
636
|
+
public void setAutoPlay(boolean autoPlay)
|
|
637
|
+
{
|
|
638
|
+
this.mPaused = !autoPlay;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
@Override
|
|
645
|
+
public void onPrepared(MediaPlayer mp)
|
|
646
|
+
{
|
|
647
|
+
|
|
648
|
+
mMediaPlayerValid = true;
|
|
649
|
+
mVideoDuration = mp.getDuration();
|
|
650
|
+
|
|
651
|
+
HippyMap naturalSize = new HippyMap();
|
|
652
|
+
naturalSize.pushInt(EVENT_PROP_WIDTH, mp.getVideoWidth());
|
|
653
|
+
naturalSize.pushInt(EVENT_PROP_HEIGHT, mp.getVideoHeight());
|
|
654
|
+
if (mp.getVideoWidth() > mp.getVideoHeight())
|
|
655
|
+
naturalSize.pushString(EVENT_PROP_ORIENTATION, "landscape");
|
|
656
|
+
else
|
|
657
|
+
naturalSize.pushString(EVENT_PROP_ORIENTATION, "portrait");
|
|
658
|
+
|
|
659
|
+
HippyMap event = new HippyMap();
|
|
660
|
+
event.pushDouble(EVENT_PROP_DURATION, mVideoDuration / 1000.0);
|
|
661
|
+
event.pushDouble(EVENT_PROP_CURRENT_TIME, mp.getCurrentPosition() / 1000.0);
|
|
662
|
+
event.pushMap(EVENT_PROP_NATURALSIZE, naturalSize);
|
|
663
|
+
// TODO: Actually check if you can.
|
|
664
|
+
event.pushBoolean(EVENT_PROP_FAST_FORWARD, true);
|
|
665
|
+
event.pushBoolean(EVENT_PROP_SLOW_FORWARD, true);
|
|
666
|
+
event.pushBoolean(EVENT_PROP_SLOW_REVERSE, true);
|
|
667
|
+
event.pushBoolean(EVENT_PROP_REVERSE, true);
|
|
668
|
+
event.pushBoolean(EVENT_PROP_FAST_FORWARD, true);
|
|
669
|
+
event.pushBoolean(EVENT_PROP_STEP_BACKWARD, true);
|
|
670
|
+
event.pushBoolean(EVENT_PROP_STEP_FORWARD, true);
|
|
671
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_LOAD.toString(), event);
|
|
672
|
+
|
|
673
|
+
applyModifiers(mPaused);
|
|
674
|
+
|
|
675
|
+
if (mUseNativeControls)
|
|
676
|
+
{
|
|
677
|
+
initializeMediaControllerIfNeeded();
|
|
678
|
+
mediaController.setMediaPlayer(this);
|
|
679
|
+
mediaController.setAnchorView(this);
|
|
680
|
+
|
|
681
|
+
videoControlHandler.post(new Runnable()
|
|
682
|
+
{
|
|
683
|
+
@Override
|
|
684
|
+
public void run()
|
|
685
|
+
{
|
|
686
|
+
mediaController.setEnabled(true);
|
|
687
|
+
mediaController.show();
|
|
688
|
+
}
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
selectTimedMetadataTrack(mp);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
@Override
|
|
696
|
+
public boolean onError(MediaPlayer mp, int what, int extra)
|
|
697
|
+
{
|
|
698
|
+
|
|
699
|
+
HippyMap error = new HippyMap();
|
|
700
|
+
error.pushInt(EVENT_PROP_WHAT, what);
|
|
701
|
+
error.pushInt(EVENT_PROP_EXTRA, extra);
|
|
702
|
+
HippyMap event = new HippyMap();
|
|
703
|
+
event.pushMap(EVENT_PROP_ERROR, error);
|
|
704
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_ERROR.toString(), event);
|
|
705
|
+
return true;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
@Override
|
|
709
|
+
public boolean onInfo(MediaPlayer mp, int what, int extra)
|
|
710
|
+
{
|
|
711
|
+
switch (what)
|
|
712
|
+
{
|
|
713
|
+
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
|
|
714
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_STALLED.toString(), new HippyMap());
|
|
715
|
+
break;
|
|
716
|
+
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
|
|
717
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_RESUME.toString(), new HippyMap());
|
|
718
|
+
break;
|
|
719
|
+
case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
|
|
720
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_READY_FOR_DISPLAY.toString(), new HippyMap());
|
|
721
|
+
break;
|
|
722
|
+
|
|
723
|
+
default:
|
|
724
|
+
}
|
|
725
|
+
return false;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
@Override
|
|
729
|
+
public void onBufferingUpdate(MediaPlayer mp, int percent)
|
|
730
|
+
{
|
|
731
|
+
selectTimedMetadataTrack(mp);
|
|
732
|
+
mVideoBufferedDuration = (int) Math.round((double) (mVideoDuration * percent) / 100.0);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
public void onSeekComplete(MediaPlayer mp)
|
|
736
|
+
{
|
|
737
|
+
HippyMap event = new HippyMap();
|
|
738
|
+
event.pushDouble(EVENT_PROP_CURRENT_TIME, getCurrentPosition() / 1000.0);
|
|
739
|
+
event.pushDouble(EVENT_PROP_SEEK_TIME, mSeekTime / 1000.0);
|
|
740
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_SEEK.toString(), event);
|
|
741
|
+
mSeekTime = 0;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
@Override
|
|
745
|
+
public void seekTo(int msec)
|
|
746
|
+
{
|
|
747
|
+
if (mMediaPlayerValid)
|
|
748
|
+
{
|
|
749
|
+
mSeekTime = msec;
|
|
750
|
+
super.seekTo(msec);
|
|
751
|
+
if (isCompleted && mVideoDuration != 0 && msec < mVideoDuration)
|
|
752
|
+
{
|
|
753
|
+
isCompleted = false;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
@Override
|
|
759
|
+
public int getBufferPercentage()
|
|
760
|
+
{
|
|
761
|
+
return 0;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
@Override
|
|
765
|
+
public boolean canPause()
|
|
766
|
+
{
|
|
767
|
+
return true;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
@Override
|
|
771
|
+
public boolean canSeekBackward()
|
|
772
|
+
{
|
|
773
|
+
return true;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
@Override
|
|
777
|
+
public boolean canSeekForward()
|
|
778
|
+
{
|
|
779
|
+
return true;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
@Override
|
|
783
|
+
public int getAudioSessionId()
|
|
784
|
+
{
|
|
785
|
+
return 0;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
@Override
|
|
789
|
+
public void onCompletion(MediaPlayer mp)
|
|
790
|
+
{
|
|
791
|
+
isCompleted = true;
|
|
792
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_END.toString(), null);
|
|
793
|
+
if (!mRepeat)
|
|
794
|
+
{
|
|
795
|
+
setKeepScreenOn(false);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// This is not fully tested and does not work for all forms of timed metadata
|
|
800
|
+
@TargetApi(23) // 6.0
|
|
801
|
+
public class TimedMetaDataAvailableListener implements MediaPlayer.OnTimedMetaDataAvailableListener
|
|
802
|
+
{
|
|
803
|
+
public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data)
|
|
804
|
+
{
|
|
805
|
+
HippyMap event = new HippyMap();
|
|
806
|
+
|
|
807
|
+
String rawMeta = new String(data.getMetaData(), Charset.forName("UTF-8"));
|
|
808
|
+
HippyMap id3 = new HippyMap();
|
|
809
|
+
|
|
810
|
+
id3.pushString(EVENT_PROP_METADATA_VALUE, rawMeta.substring(rawMeta.lastIndexOf("\u0003") + 1));
|
|
811
|
+
id3.pushString(EVENT_PROP_METADATA_IDENTIFIER, "id3/TDEN");
|
|
812
|
+
|
|
813
|
+
HippyArray metadata = new HippyArray();
|
|
814
|
+
|
|
815
|
+
metadata.pushMap(id3);
|
|
816
|
+
|
|
817
|
+
event.pushArray(EVENT_PROP_METADATA, metadata);
|
|
818
|
+
event.pushDouble(EVENT_PROP_TARGET, getId());
|
|
819
|
+
|
|
820
|
+
mEventEmitter.receiveUIComponentEvent(getId(), Events.EVENT_TIMED_METADATA.toString(), event);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
@Override
|
|
825
|
+
protected void onDetachedFromWindow()
|
|
826
|
+
{
|
|
827
|
+
mMediaPlayerValid = false;
|
|
828
|
+
super.onDetachedFromWindow();
|
|
829
|
+
setKeepScreenOn(false);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
@Override
|
|
833
|
+
protected void onAttachedToWindow()
|
|
834
|
+
{
|
|
835
|
+
super.onAttachedToWindow();
|
|
836
|
+
|
|
837
|
+
if (mMainVer > 0)
|
|
838
|
+
{
|
|
839
|
+
setSrc(mSrcUriString, mSrcType, mSrcIsNetwork, mSrcIsAsset, mRequestHeaders, mMainVer, mPatchVer);
|
|
840
|
+
}
|
|
841
|
+
else
|
|
842
|
+
{
|
|
843
|
+
setSrc(mSrcUriString, mSrcType, mSrcIsNetwork, mSrcIsAsset, mRequestHeaders);
|
|
844
|
+
}
|
|
845
|
+
setKeepScreenOn(true);
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// @Override
|
|
849
|
+
// public void onHostPause() {
|
|
850
|
+
// if (mMediaPlayerValid && !mPaused && !mPlayInBackground) {
|
|
851
|
+
// /* Pause the video in background
|
|
852
|
+
// * Don't update the paused prop, developers should be able to update it on background
|
|
853
|
+
// * so that when you return to the app the video is paused
|
|
854
|
+
// */
|
|
855
|
+
// mBackgroundPaused = true;
|
|
856
|
+
// mMediaPlayer.pause();
|
|
857
|
+
// }
|
|
858
|
+
// }
|
|
859
|
+
//
|
|
860
|
+
// @Override
|
|
861
|
+
// public void onHostResume() {
|
|
862
|
+
// mBackgroundPaused = false;
|
|
863
|
+
// if (mMediaPlayerValid && !mPlayInBackground && !mPaused) {
|
|
864
|
+
// new Handler().post(new Runnable() {
|
|
865
|
+
// @Override
|
|
866
|
+
// public void run() {
|
|
867
|
+
// // Restore original state
|
|
868
|
+
// setPausedModifier(false);
|
|
869
|
+
// }
|
|
870
|
+
// });
|
|
871
|
+
// }
|
|
872
|
+
// }
|
|
873
|
+
//
|
|
874
|
+
// @Override
|
|
875
|
+
// public void onHostDestroy() {
|
|
876
|
+
// }
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
public static Map<String, String> toStringMap(HippyMap readableMap)
|
|
880
|
+
{
|
|
881
|
+
Map<String, String> result = new HashMap<>();
|
|
882
|
+
if (readableMap == null)
|
|
883
|
+
return result;
|
|
884
|
+
Set<String> keySet = readableMap.keySet();
|
|
885
|
+
Iterator<String> iterator = keySet.iterator();
|
|
886
|
+
while (iterator.hasNext())
|
|
887
|
+
{
|
|
888
|
+
String key = iterator.next();
|
|
889
|
+
result.put(key, readableMap.getString(key));
|
|
890
|
+
}
|
|
891
|
+
return result;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
// Select track (so we can use it to listen to timed meta data updates)
|
|
895
|
+
private void selectTimedMetadataTrack(MediaPlayer mp)
|
|
896
|
+
{
|
|
897
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
|
|
898
|
+
{
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
try
|
|
902
|
+
{ // It's possible this could throw an exception if the framework doesn't support getting track info
|
|
903
|
+
MediaPlayer.TrackInfo[] trackInfo = mp.getTrackInfo();
|
|
904
|
+
for (int i = 0; i < trackInfo.length; ++i)
|
|
905
|
+
{
|
|
906
|
+
if (trackInfo[i].getTrackType() == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT)
|
|
907
|
+
{
|
|
908
|
+
mp.selectTrack(i);
|
|
909
|
+
break;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
catch (Exception e)
|
|
914
|
+
{
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|