Commit a008f33d by 代凡

添加native播放界面及逻辑

parent 75f2c006
......@@ -95,14 +95,15 @@ def enableProguardInReleaseBuilds = false
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
applicationId "com.polyvrncloudclassdemo"
applicationId "com.easefun.polyvsdk.cloudclass"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
multiDexEnabled true
ndk {
abiFilters "armeabi-v7a", "x86"
}
......@@ -134,9 +135,17 @@ android {
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
compile project(':react-native-gesture-handler')
compile project(':react-native-reanimated')
api project(':polyvsdk')
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
implementation "com.facebook.react:react-native:+" // From node_modules
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.polyvrncloudclassdemo">
xmlns:tools="http://schemas.android.com/tools"
package="com.easefun.polyvsdk.cloudclass">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:theme="@style/AppTheme">
android:name=".MainApplication"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@drawable/ic_launcher"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
tools:replace="android:icon,android:theme">
<activity
android:name=".MainActivity"
android:name="com.easefun.polyvsdk.cloudclass.MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
......
package com.polyvrncloudclassdemo;
package com.easefun.polyvsdk.cloudclass;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
public class MainActivity extends ReactActivity {
......@@ -12,4 +15,14 @@ public class MainActivity extends ReactActivity {
protected String getMainComponentName() {
return "PolyvRNCloudClassDemo";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
}
package com.polyvrncloudclassdemo;
package com.easefun.polyvsdk.cloudclass;
import android.app.Application;
import com.blankj.utilcode.util.AppUtils;
import com.easefun.polyv.cloudclassdemo.PolyvCloudClassApp;
import com.easefun.polyv.foundationsdk.utils.PolyvAppUtils;
import com.easefun.polyvsdk.cloudclass.rn.PolyvCloudClassRNPackage;
import com.facebook.react.ReactApplication;
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
import com.swmansion.reanimated.ReanimatedPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
......@@ -11,7 +17,7 @@ import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
public class MainApplication extends PolyvCloudClassApp implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
......@@ -22,7 +28,10 @@ public class MainApplication extends Application implements ReactApplication {
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
new MainReactPackage(),
new RNGestureHandlerPackage(),
new ReanimatedPackage(),
new PolyvCloudClassRNPackage()
);
}
......@@ -39,6 +48,7 @@ public class MainApplication extends Application implements ReactApplication {
@Override
public void onCreate() {
PolyvAppUtils.init(this);
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
......
package com.easefun.polyvsdk.cloudclass;
import android.app.Application;
import android.content.Context;
import com.easefun.polyv.businesssdk.vodplayer.PolyvVodSDKClient;
import com.easefun.polyv.cloudclass.config.PolyvLiveSDKClient;
import com.easefun.polyv.foundationsdk.log.PolyvCommonLog;
/**
* @author df
* @create 2019/9/6
* @Describe
*/
public class PolyvInitManager {
public static void init(String vodKey, String decodeKey, String decodeIv, Context context){
// Normal app init code...
PolyvCommonLog.setDebug(true);
PolyvLiveSDKClient liveSDKClient = PolyvLiveSDKClient.getInstance();
liveSDKClient.initContext(null);
PolyvVodSDKClient client = PolyvVodSDKClient.getInstance();
//使用SDK加密串来配置
client.setConfig(vodKey, decodeKey, decodeIv);
}
}
package com.easefun.polyvsdk.cloudclass.rn;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author df
* @create 2019/9/6
* @Describe
*/
public class PolyvCloudClassRNPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new PolyvCloudClassRNModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
package com.easefun.polyvsdk.cloudclass.rn;
/**
* @author df
* @create 2019/1/26
* @Describe
*/
public class PolyvErrorCode {
/**
* code,返回码定义:
* 0 成功
* -1 AppId为空
* -2 AppSecret为空
* -3 viewerId为空
* -4 UserId为空
* -5 ChannelId为空
* -6 频道加载失败
*/
public final static int success = 0;
public final static int noAppId = -1;
public final static int noAppScrect = -2;
public final static int noViewId = -3;
public final static int noUserId = -4;
public final static int noChannelId = -5;
public final static int noVideoId = -6;
public final static int noVodKey = -7;
public final static int noDecodeKey = -8;
public final static int noDecodeIv = -9;
public final static int channleLoadFailed = -10;
public static String getDesc(int code) {
switch (code) {
case PolyvErrorCode.success:
return "成功";
case PolyvErrorCode.noAppId:
return "AppId为空";
case PolyvErrorCode.noAppScrect:
return "AppSecret为空";
case PolyvErrorCode.noViewId:
return "viewerId为空";
case PolyvErrorCode.noUserId:
return "UserId为空";
case PolyvErrorCode.noChannelId:
return "ChannelId为空";
case PolyvErrorCode.noVideoId:
return "videoId为空";
case PolyvErrorCode.channleLoadFailed:
return "频道加载失败";
case PolyvErrorCode.noVodKey:
return "VodKey为空";
case PolyvErrorCode.noDecodeKey:
return "DecodeKey为空";
case PolyvErrorCode.noDecodeIv:
return "DecodeIv为空";
default:
return "";
}
}
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "27.0.3"
minSdkVersion = 16
compileSdkVersion = 27
targetSdkVersion = 26
supportLibVersion = "27.1.1"
}
repositories {
google()
jcenter()
......@@ -42,7 +35,6 @@ allprojects {
}
}
ext {
buildToolsVersion = "27.0.3"
supportLibVersion = "27.1.1"
compileSdkVersion = 27
minSdkVersion = 16
......
apply plugin: 'com.android.library'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
api 'com.android.support:design:27.1.1'
api 'com.easefun.polyv:polyvSDKCloudClass:0.8.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
package com.easefun.polyv.commonui;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.polyv.easefun.commonui.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.easefun.polyv.commonui" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link href="./css/app.973c3fa15a0659d368b8.css" rel="stylesheet"></head>
<body>
<div id="answerCard" class="ppt-answer-card-wrap"></div>
<div id="questionnaire" class="ppt-questionnaire-wrap ppt-hide"></div>
<div id="lottery" class="ppt-lottery-wrap"></div>
<div id="sign" class="ppt-sign-wrap"></div>
<div id="announcement" class="ppt-announcement-wrap ppt-hide">
<div class="ppt-announcement">
<div class="ppt-announcement-head">
公告
<span data-el="close">×</span>
</div>
<div class="ppt-announcement-content" data-el="content">暂无公告</div>
<div class="ppt-announcement-foot">
<span data-el="know">知道了</span>
</div>
</div>
</div>
<script type="text/javascript" src="./vendors~app.973c3fa15a0659d368b8.bundle.js"></script><script type="text/javascript" src="./app.973c3fa15a0659d368b8.bundle.js"></script></body>
</html>
\ No newline at end of file
package com.easefun.polyv.commonui;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.easefun.polyv.businesssdk.api.common.meidaControl.IPolyvMediaController;
import com.easefun.polyv.businesssdk.api.common.player.microplayer.PolyvCommonVideoView;
import com.easefun.polyv.businesssdk.model.video.PolyvBitrateVO;
import com.easefun.polyv.businesssdk.model.video.PolyvDefinitionVO;
import com.easefun.polyv.businesssdk.model.video.PolyvLiveLinesVO;
import com.easefun.polyv.commonui.player.adapter.PolyvBitRateAdapter;
import com.easefun.polyv.foundationsdk.log.PolyvCommonLog;
import com.easefun.polyv.foundationsdk.utils.PolyvScreenUtils;
import java.util.List;
import java.util.ListIterator;
/**
* @author df
* @create 2018/8/16
* @Describe 公共的控制类
*/
public abstract class PolyvCommonMediacontroller<T extends PolyvCommonVideoView> extends FrameLayout
implements IPolyvMediaController<T>, View.OnClickListener {
private static final String TAG = "PolyvCommonMediacontoller";
protected View rootView, parentView;
protected TextView bitrateChange;
protected TextView bitrateChangeLand;
//控制栏显示的时间
protected static final int SHOW_TIME = 5000;
protected boolean showPPTSubView = true;//ppt显示在副屏
protected RelativeLayout videoControllerPort;
protected RelativeLayout videoControllerLand;
protected Activity context;
protected T polyvVideoView;
protected volatile int currentBitratePos;
protected PolyvBitrateVO polyvLiveBitrateVO;
//更多
protected ImageView ivMorePortrait;
protected ImageView ivMoreLand;
private ViewGroup contentView, fullVideoViewParent;
private ViewGroup.LayoutParams portraitLP;//(需要移动的整个播放器布局)在竖屏下的LayoutParams
private ViewGroup fullVideoView;//需要移动的整个播放器布局
private static final String landTag = "land";
private static final String portraitTag = "portrait";
private Runnable hideTask = new Runnable() {
@Override
public void run() {
hide();
}
};
public PolyvCommonMediacontroller(@NonNull Context context) {
this(context, null);
}
public PolyvCommonMediacontroller(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public PolyvCommonMediacontroller(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialView();
}
protected abstract void initialView();
/**
* 切换主副平
*/
public abstract void changePPTVideoLocation();
@Override
public void setMediaPlayer(T player) {
polyvVideoView = player;
}
@Override
public T getMediaPlayer() {
return polyvVideoView;
}
@Override
public void changeToLandscape() {
if(PolyvScreenUtils.isLandscape(context)){
return;
}
// context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
PolyvScreenUtils.setLandscape(context);
hide();
}
public void setLandscapeController() {
post(new Runnable() {
@Override
public void run() {
// // 通过移除整个播放器布局到窗口的上层布局中,并改变整个播放器布局的大小,实现全屏的播放器。
// if (fullVideoView == null) {
// fullVideoView = ((ViewGroup) polyvVideoView.getParent().getParent());
// fullVideoViewParent = (ViewGroup) fullVideoView.getParent();
// contentView = (ViewGroup) context.findViewById(Window.ID_ANDROID_CONTENT);
// }
// if (!landTag.equals(fullVideoView.getTag())) {
// fullVideoView.setTag(landTag);
// portraitLP = fullVideoView.getLayoutParams();
// fullVideoViewParent.removeView(fullVideoView);
// FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
// fullVideoView.setLayoutParams(flp);
// contentView.addView(fullVideoView);
// }
ViewGroup.LayoutParams vlp = parentView.getLayoutParams();
vlp.width = ViewGroup.LayoutParams.MATCH_PARENT;
vlp.height = ViewGroup.LayoutParams.MATCH_PARENT;
videoControllerPort.setVisibility(View.GONE);
videoControllerLand.setVisibility(View.VISIBLE);
}
});
}
@Override
public void changeToPortrait() {
if(PolyvScreenUtils.isPortrait(context)){
return;
}
// context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
PolyvScreenUtils.setPortrait(context);
hide();
}
@Override
public void initialConfig(ViewGroup view) {
parentView = view;
changeToPortrait();
}
private void setPortraitController() {
post(new Runnable() {
@Override
public void run() {