diff --git a/OnLive/.gitignore b/OnLive/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/OnLive/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/OnLive/build.gradle b/OnLive/build.gradle deleted file mode 100644 index e01a34a..0000000 --- a/OnLive/build.gradle +++ /dev/null @@ -1,52 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion - - lintOptions { - abortOnError false - } - defaultConfig { - applicationId "com.frank.living" - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode rootProject.ext.versionCode - versionName rootProject.ext.versionName - flavorDimensions "800400" - - ndk { - abiFilters 'armeabi-v7a', 'arm64-v8a' - } - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - productFlavors { - all32 { minSdkVersion rootProject.ext.minSdkVersion } - all64 { minSdkVersion rootProject.ext.minSdkVersion } - } - - sourceSets { - main { - jniLibs.srcDirs = ['libs'] - } - } -} - -dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation "androidx.appcompat:appcompat:$rootProject.appcompatVersion" - implementation "androidx.preference:preference:$rootProject.preferenceVersion" - implementation "androidx.annotation:annotation:$rootProject.annotationVersion" - implementation "androidx.recyclerview:recyclerview:$rootProject.recyclerviewVersion" - - implementation "com.squareup:otto:$rootProject.ottoVersion" - - implementation "tv.danmaku.ijk.media:ijkplayer-java:$rootProject.ijkVersion" - implementation "tv.danmaku.ijk.media:ijkplayer-exo:$rootProject.ijkVersion" - -} diff --git a/OnLive/libs/arm64-v8a/libijkffmpeg.so b/OnLive/libs/arm64-v8a/libijkffmpeg.so deleted file mode 100644 index bb6f815..0000000 Binary files a/OnLive/libs/arm64-v8a/libijkffmpeg.so and /dev/null differ diff --git a/OnLive/libs/arm64-v8a/libijkplayer.so b/OnLive/libs/arm64-v8a/libijkplayer.so deleted file mode 100644 index 7d655e5..0000000 Binary files a/OnLive/libs/arm64-v8a/libijkplayer.so and /dev/null differ diff --git a/OnLive/libs/arm64-v8a/libijksdl.so b/OnLive/libs/arm64-v8a/libijksdl.so deleted file mode 100644 index 43b157c..0000000 Binary files a/OnLive/libs/arm64-v8a/libijksdl.so and /dev/null differ diff --git a/OnLive/libs/armeabi-v7a/libijkffmpeg.so b/OnLive/libs/armeabi-v7a/libijkffmpeg.so deleted file mode 100644 index 08ced5c..0000000 Binary files a/OnLive/libs/armeabi-v7a/libijkffmpeg.so and /dev/null differ diff --git a/OnLive/libs/armeabi-v7a/libijkplayer.so b/OnLive/libs/armeabi-v7a/libijkplayer.so deleted file mode 100644 index 8836b05..0000000 Binary files a/OnLive/libs/armeabi-v7a/libijkplayer.so and /dev/null differ diff --git a/OnLive/libs/armeabi-v7a/libijksdl.so b/OnLive/libs/armeabi-v7a/libijksdl.so deleted file mode 100644 index 266d0b5..0000000 Binary files a/OnLive/libs/armeabi-v7a/libijksdl.so and /dev/null differ diff --git a/OnLive/proguard-rules.pro b/OnLive/proguard-rules.pro deleted file mode 100644 index 034485d..0000000 --- a/OnLive/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /opt/android/ADK/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# 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 *; -#} diff --git a/OnLive/src/main/AndroidManifest.xml b/OnLive/src/main/AndroidManifest.xml deleted file mode 100644 index 59c8ed0..0000000 --- a/OnLive/src/main/AndroidManifest.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OnLive/src/main/java/com/frank/living/activity/MultiScreenActivity.java b/OnLive/src/main/java/com/frank/living/activity/MultiScreenActivity.java deleted file mode 100644 index 7ea40e9..0000000 --- a/OnLive/src/main/java/com/frank/living/activity/MultiScreenActivity.java +++ /dev/null @@ -1,469 +0,0 @@ -package com.frank.living.activity; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.PowerManager; -import android.os.Process; - -import androidx.appcompat.app.AppCompatActivity; - -import android.os.Bundle; -import android.text.TextUtils; -import android.util.Log; -import android.view.View; - -import com.frank.living.R; -import com.frank.living.constant.Constants; -import com.frank.living.listener.OnDoubleClickListener; -import com.frank.living.listener.IjkPlayerListener; -import com.frank.living.widget.IjkVideoView; - -import java.util.HashMap; -import java.util.TreeMap; - -import tv.danmaku.ijk.media.player.IMediaPlayer; -import tv.danmaku.ijk.media.player.IjkMediaPlayer; - -/** - * multi screen living - * Created by xufulong on 2019/01/04 - */ -public class MultiScreenActivity extends AppCompatActivity { - - private static final String TAG = MultiScreenActivity.class.getSimpleName(); - - private IjkVideoView mVideoView1; - private IjkVideoView mVideoView2; - private IjkVideoView mVideoView3; - private IjkVideoView mVideoView4; - - private View divider1; - private View divider2; - - private IMediaPlayer ijkPlayer; - private CustomReceiver customReceiver; - private String ipAddress; - - //is multi-screen mode or full-screen mode - private boolean isMultiScreen; - //relationship of between client id and channel number - private HashMap clientMap = new HashMap<>(); - //record each channel state - private TreeMap channelMap = new TreeMap<>(); - - private String url = ""; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_multi_screen); - - parseIntent(); - registerBroadcast(); - - initView(); - initListener(); - setupView(); - wakeUp(); - - } - - private void initView() { - mVideoView1 = findViewById(R.id.video_view1); - mVideoView2 = findViewById(R.id.video_view2); - mVideoView3 = findViewById(R.id.video_view3); - mVideoView4 = findViewById(R.id.video_view4); - - divider1 = findViewById(R.id.divider1); - divider2 = findViewById(R.id.divider2); - } - - private void initListener() { - mVideoView1.setOnTouchListener(new OnDoubleClickListener(new OnDoubleClickListener.OnDoubleClick() { - @Override - public void onDouble() { - changeScreenMode(1); - } - })); - mVideoView2.setOnTouchListener(new OnDoubleClickListener(new OnDoubleClickListener.OnDoubleClick() { - @Override - public void onDouble() { - changeScreenMode(2); - } - })); - mVideoView3.setOnTouchListener(new OnDoubleClickListener(new OnDoubleClickListener.OnDoubleClick() { - @Override - public void onDouble() { - changeScreenMode(3); - } - })); - mVideoView4.setOnTouchListener(new OnDoubleClickListener(new OnDoubleClickListener.OnDoubleClick() { - @Override - public void onDouble() { - changeScreenMode(4); - } - })); - } - - private void setupView() { - //default full screen - enterFullScreen(1); - mVideoView1.setVideoPath(url); - mVideoView1.setIjkPlayerListener(new IjkPlayerListener() { - @Override - public void onIjkPlayer(IjkMediaPlayer ijkMediaPlayer) { - //setting ijkPlayer option - setOptions(ijkMediaPlayer); - } - }); - mVideoView1.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() { - @Override - public void onPrepared(IMediaPlayer iMediaPlayer) { - - ijkPlayer = iMediaPlayer; - } - }); - mVideoView1.start(); - } - - /** - * parse params - */ - private void parseIntent() { - for (int i = 1; i <= 4; i++) { - channelMap.put(i, false); - } - clientMap.put(ipAddress, 1); - channelMap.put(1, true); - - Intent intent = getIntent(); - String url = intent.getStringExtra("url"); - if (!TextUtils.isEmpty(url)) { - this.url = url; - } - String ip = intent.getStringExtra("ip"); - if (!TextUtils.isEmpty(ip)) { - ipAddress = ip; - } - } - - //wake up the screen - private void wakeUp() { - PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); - if (powerManager == null) - return; - PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK - | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG); - wakeLock.acquire(1000); - wakeLock.release(); - } - - /** - * config the options of ijkPlayer - */ - private void setOptions(IjkMediaPlayer ijkPlayer) { - if (ijkPlayer == null) - return; - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "fast", 1);//no extra optimize - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 200);//size of probe data - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1); - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);//enable cache or not - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1); - //0:disable 1:enable - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0);//enable hardware decode or not - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 0);//auto rotate - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 0); - - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", 0);//max buffer size - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 2);//minimum frame size - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 30);//maximum cached duration - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1); - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer"); - //max analyzed duration - ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzedmaxduration", 100); - //ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");//using tcp or udp - } - - /** - * register broadcast - */ - private void registerBroadcast() { - customReceiver = new CustomReceiver(); - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Constants.ACTION_CLIENT_REMOVE); - intentFilter.addAction(Constants.ACTION_CLIENT_ADD); - registerReceiver(customReceiver, intentFilter); - } - - /** - * unregister broadcast - */ - private void unregisterBroadcast() { - if (customReceiver != null) { - unregisterReceiver(customReceiver); - customReceiver = null; - } - } - - /** - * custom broadcast receiver - */ - private class CustomReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) - return; - Log.e(TAG, "onReceive=" + action); - switch (action) { - case Constants.ACTION_CLIENT_REMOVE://remove client - int num = intent.getIntExtra("clientNum", 0); - if (num == 0) { - Process.killProcess(Process.myPid()); - } else if (num > 0) { - String ipAddress = intent.getStringExtra("ipAddress"); - int target = clientMap.get(ipAddress); - removeClient(target); - clientMap.remove(ipAddress); - channelMap.put(target, false); - if (num == 1) { - int castingChannel = getCastingChannel(); - enterFullScreen(castingChannel); - } - } - break; - case Constants.ACTION_CLIENT_ADD://add client - int clientNum = intent.getIntExtra("clientNum", 0); - String otherUrl = intent.getStringExtra("url"); - String ipAddress = intent.getStringExtra("ip"); - //select the idle channel - int channel = selectIdleChannel(clientNum); - clientMap.put(ipAddress, channel); - channelMap.put(channel, true); - addClient(channel, otherUrl); - //switch multi-screen mode - if (clientNum == 2) { - exitFullScreen(); - } - break; - default: - break; - } - } - } - - /** - * select the first idle channel - * - * @param clientNum clientNum - * @return idleChannel - */ - private int selectIdleChannel(int clientNum) { - for (int channel = 1; channel < clientNum; channel++) { - if (!channelMap.get(channel)) { - return channel; - } - } - return clientNum; - } - - /** - * get current casting channel - * - * @return idleChannel - */ - private int getCastingChannel() { - for (int channel = 1; channel <= 4; channel++) { - if (channelMap.get(channel)) { - return channel; - } - } - return 0; - } - - /** - * add client to casting - * - * @param target target - * @param clientUrl clientUrl - */ - private void addClient(int target, String clientUrl) { - switch (target) { - case 1: - mVideoView1.setVisibility(View.VISIBLE); - mVideoView1.setVideoPath(clientUrl); - mVideoView1.start(); - break; - case 2: - mVideoView2.setVisibility(View.VISIBLE); - mVideoView2.setVideoPath(clientUrl); - mVideoView2.start(); - break; - case 3: - mVideoView3.setVisibility(View.VISIBLE); - mVideoView3.setVideoPath(clientUrl); - mVideoView3.start(); - break; - case 4: - mVideoView4.setVisibility(View.VISIBLE); - mVideoView4.setVideoPath(clientUrl); - mVideoView4.start(); - break; - default: - break; - } - } - - /** - * remove client - * - * @param target target - */ - private void removeClient(int target) { - switch (target) { - case 1: - mVideoView1.stopPlayback(); - mVideoView1.setVisibility(View.GONE); - break; - case 2: - mVideoView2.stopPlayback(); - mVideoView2.setVisibility(View.GONE); - break; - case 3: - mVideoView3.stopPlayback(); - mVideoView3.setVisibility(View.GONE); - break; - case 4: - mVideoView4.stopPlayback(); - mVideoView4.setVisibility(View.GONE); - break; - default: - break; - } - } - - /** - * hide divider in multi-screen mode - */ - private void hideDivider() { - divider1.setVisibility(View.GONE); - divider2.setVisibility(View.GONE); - } - - /** - * show divider in multi-screen mode - */ - private void showDivider() { - divider1.setVisibility(View.VISIBLE); - divider2.setVisibility(View.VISIBLE); - } - - /** - * enter full-screen mode - * - * @param channel channel - */ - private void enterFullScreen(int channel) { - hideDivider(); - switch (channel) { - case 1: - mVideoView1.setRenderViewVisible(); - mVideoView2.setRenderViewGone(); - mVideoView3.setRenderViewGone(); - mVideoView4.setRenderViewGone(); - - mVideoView1.setVisibility(View.VISIBLE); - mVideoView2.setVisibility(View.GONE); - mVideoView3.setVisibility(View.GONE); - mVideoView4.setVisibility(View.GONE); - break; - case 2: - mVideoView1.setRenderViewGone(); - mVideoView2.setRenderViewVisible(); - mVideoView3.setRenderViewGone(); - mVideoView4.setRenderViewGone(); - - mVideoView1.setVisibility(View.GONE); - mVideoView2.setVisibility(View.VISIBLE); - mVideoView3.setVisibility(View.GONE); - mVideoView4.setVisibility(View.GONE); - break; - case 3: - mVideoView1.setRenderViewGone(); - mVideoView2.setRenderViewGone(); - mVideoView3.setRenderViewVisible(); - mVideoView4.setRenderViewGone(); - - mVideoView1.setVisibility(View.GONE); - mVideoView2.setVisibility(View.GONE); - mVideoView3.setVisibility(View.VISIBLE); - mVideoView4.setVisibility(View.GONE); - break; - case 4: - mVideoView1.setRenderViewGone(); - mVideoView2.setRenderViewGone(); - mVideoView3.setRenderViewGone(); - mVideoView4.setRenderViewVisible(); - - mVideoView1.setVisibility(View.GONE); - mVideoView2.setVisibility(View.GONE); - mVideoView3.setVisibility(View.GONE); - mVideoView4.setVisibility(View.VISIBLE); - break; - default: - break; - } - } - - /** - * exit full-screen mode - */ - private void exitFullScreen() { - mVideoView1.setRenderViewVisible(); - mVideoView2.setRenderViewVisible(); - mVideoView3.setRenderViewVisible(); - mVideoView4.setRenderViewVisible(); - - showDivider(); - mVideoView1.setVisibility(View.VISIBLE); - mVideoView2.setVisibility(View.VISIBLE); - mVideoView3.setVisibility(View.VISIBLE); - mVideoView4.setVisibility(View.VISIBLE); - } - - /** - * switch screen mode - * - * @param channel channel - */ - private void changeScreenMode(int channel) { - isMultiScreen = !isMultiScreen; - if (isMultiScreen) { - enterFullScreen(channel); - } else { - exitFullScreen(); - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - - unregisterBroadcast(); - - mVideoView1.stopPlayback(); - mVideoView1.release(true); - mVideoView2.stopPlayback(); - mVideoView2.release(true); - mVideoView3.stopPlayback(); - mVideoView3.release(true); - mVideoView4.stopPlayback(); - mVideoView4.release(true); - - IjkMediaPlayer.native_profileEnd(); - } - -} - diff --git a/OnLive/src/main/java/com/frank/living/activity/RtspLiveActivity.java b/OnLive/src/main/java/com/frank/living/activity/RtspLiveActivity.java deleted file mode 100644 index d6bd727..0000000 --- a/OnLive/src/main/java/com/frank/living/activity/RtspLiveActivity.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.frank.living.activity; - -import android.Manifest; -import android.content.pm.PackageManager; -import android.graphics.Bitmap; -import android.os.Bundle; - -import androidx.appcompat.app.AppCompatActivity; - -import android.os.Environment; -import android.util.Log; -import android.view.View; -import android.widget.ImageButton; -import android.widget.TableLayout; - -import com.frank.living.R; -import com.frank.living.listener.IjkPlayerListener; - -import androidx.core.app.ActivityCompat; -import tv.danmaku.ijk.media.player.IjkMediaPlayer; - -import com.frank.living.util.PhotoUtil; -import com.frank.living.widget.IjkVideoView; - -import java.io.File; - -public class RtspLiveActivity extends AppCompatActivity implements IjkPlayerListener, View.OnClickListener { - - private final static String TAG = RtspLiveActivity.class.getSimpleName(); - - private IjkMediaPlayer ijkMediaPlayer; - private IjkVideoView mVideoView; - private ImageButton btnPlay; - private ImageButton btnSound; - private boolean isPause; - private boolean isSilence; - private String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}; - - private final static String url = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_live); - - requestPermission(); - init(); - - } - - private void init() { - IjkMediaPlayer.loadLibrariesOnce(null); - IjkMediaPlayer.native_profileBegin("libijkplayer.so"); - - TableLayout mHudView = findViewById(R.id.hud_view); - mVideoView = findViewById(R.id.video_view); - mVideoView.setHudView(mHudView); - mVideoView.setIjkPlayerListener(this); - mVideoView.setVideoPath(url); - mVideoView.start(); - - btnPlay = findViewById(R.id.btn_play); - btnPlay.setOnClickListener(this); - btnSound = findViewById(R.id.btn_sound); - btnSound.setOnClickListener(this); - ImageButton btnScreenShot = findViewById(R.id.btn_screenshot); - btnScreenShot.setOnClickListener(this); - } - - private void requestPermission() { - if (ActivityCompat.checkSelfPermission(this, permissions[0]) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(this, permissions, 1234); - } - } - - private void initOptions() { - if (ijkMediaPlayer == null) - return; - Log.e(TAG, "initOptions"); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "fast", 1); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 200); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1); - //0:disable 1:enable - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 0); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 0); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", 0); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 2); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 30); - //input buffer:don't limit the input buffer size (useful with realtime streams) - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer"); - //ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp"); - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzedmaxduration", 100); - } - - @Override - public void onIjkPlayer(IjkMediaPlayer ijkMediaPlayer) { - this.ijkMediaPlayer = ijkMediaPlayer; - initOptions(); - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.btn_play: - isPause = !isPause; - if (isPause) {//pause - mVideoView.pause(); - btnPlay.setBackgroundResource(R.drawable.ic_play); - } else {//resume - mVideoView.start(); - btnPlay.setBackgroundResource(R.drawable.ic_pause); - } - break; - case R.id.btn_sound: - isSilence = !isSilence; - if (ijkMediaPlayer == null) - return; - if (isSilence) { - ijkMediaPlayer.setVolume(0, 0); - btnSound.setBackgroundResource(R.drawable.ic_sound); - } else { - ijkMediaPlayer.setVolume(50, 50); - btnSound.setBackgroundResource(R.drawable.ic_silence); - } - break; - case R.id.btn_screenshot: - if (mVideoView != null) { - Bitmap currentFrame = mVideoView.getCurrentFrame(); - if (currentFrame != null) { - String photoName = "img_" + System.currentTimeMillis() + ".jpg"; - String photoPath = Environment.getExternalStorageDirectory().getPath() + File.separator + photoName; - PhotoUtil.savePhoto(currentFrame, photoPath, this); - } - } - break; - default: - break; - } - } - - @Override - protected void onStop() { - super.onStop(); - - mVideoView.stopPlayback(); - mVideoView.release(true); - IjkMediaPlayer.native_profileEnd(); - } - -} diff --git a/OnLive/src/main/java/com/frank/living/config/Settings.java b/OnLive/src/main/java/com/frank/living/config/Settings.java deleted file mode 100644 index 0a8ed0d..0000000 --- a/OnLive/src/main/java/com/frank/living/config/Settings.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.config; - -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import com.frank.living.R; - -public class Settings { - private Context mAppContext; - private SharedPreferences mSharedPreferences; - - public static final int PV_PLAYER__Auto = 0; - public static final int PV_PLAYER__AndroidMediaPlayer = 1; - public static final int PV_PLAYER__IjkMediaPlayer = 2; - public static final int PV_PLAYER__IjkExoMediaPlayer = 3; - - public Settings(Context context) { - mAppContext = context.getApplicationContext(); - mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(mAppContext); - } - - public int getPlayer() { - String key = mAppContext.getString(R.string.pref_key_player); - String value = mSharedPreferences.getString(key, ""); - try { - return Integer.valueOf(value).intValue(); - } catch (NumberFormatException e) { - return 0; - } - } - - public boolean getUsingMediaCodec() { - String key = mAppContext.getString(R.string.pref_key_using_media_codec); - return mSharedPreferences.getBoolean(key, false); - } - - public boolean getUsingMediaCodecAutoRotate() { - String key = mAppContext.getString(R.string.pref_key_using_media_codec_auto_rotate); - return mSharedPreferences.getBoolean(key, false); - } - - public boolean getMediaCodecHandleResolutionChange() { - String key = mAppContext.getString(R.string.pref_key_media_codec_handle_resolution_change); - return mSharedPreferences.getBoolean(key, false); - } - - public boolean getUsingOpenSLES() { - String key = mAppContext.getString(R.string.pref_key_using_opensl_es); - return mSharedPreferences.getBoolean(key, false); - } - - public String getPixelFormat() { - String key = mAppContext.getString(R.string.pref_key_pixel_format); - return mSharedPreferences.getString(key, ""); - } - - public boolean getEnableNoView() { - String key = mAppContext.getString(R.string.pref_key_enable_no_view); - return mSharedPreferences.getBoolean(key, false); - } - - public boolean getEnableSurfaceView() { - String key = mAppContext.getString(R.string.pref_key_enable_surface_view); - return mSharedPreferences.getBoolean(key, false); - } - - public boolean getEnableTextureView() { - String key = mAppContext.getString(R.string.pref_key_enable_texture_view); - return mSharedPreferences.getBoolean(key, true); - } - - public boolean getEnableDetachedSurfaceTextureView() { - String key = mAppContext.getString(R.string.pref_key_enable_detached_surface_texture); - return mSharedPreferences.getBoolean(key, false); - } - - public boolean getUsingMediaDataSource() { - String key = mAppContext.getString(R.string.pref_key_using_mediadatasource); - return mSharedPreferences.getBoolean(key, false); - } - - public String getLastDirectory() { - String key = mAppContext.getString(R.string.pref_key_last_directory); - return mSharedPreferences.getString(key, "/"); - } - - public void setLastDirectory(String path) { - String key = mAppContext.getString(R.string.pref_key_last_directory); - mSharedPreferences.edit().putString(key, path).apply(); - } -} diff --git a/OnLive/src/main/java/com/frank/living/constant/Constants.java b/OnLive/src/main/java/com/frank/living/constant/Constants.java deleted file mode 100644 index 36adf3e..0000000 --- a/OnLive/src/main/java/com/frank/living/constant/Constants.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.frank.living.constant; - -public class Constants { - - //broadcast of add client - public final static String ACTION_CLIENT_ADD = "action.client.ADD"; - //broadcast of remove client - public final static String ACTION_CLIENT_REMOVE = "action.client.REMOVE"; - -} diff --git a/OnLive/src/main/java/com/frank/living/listener/IjkPlayerListener.java b/OnLive/src/main/java/com/frank/living/listener/IjkPlayerListener.java deleted file mode 100644 index 511ca18..0000000 --- a/OnLive/src/main/java/com/frank/living/listener/IjkPlayerListener.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.frank.living.listener; - -import tv.danmaku.ijk.media.player.IjkMediaPlayer; - -/** - * - * Created by frank on 2019/1/4. - */ - -public interface IjkPlayerListener { - - void onIjkPlayer(IjkMediaPlayer ijkMediaPlayer); - -} diff --git a/OnLive/src/main/java/com/frank/living/listener/OnDoubleClickListener.java b/OnLive/src/main/java/com/frank/living/listener/OnDoubleClickListener.java deleted file mode 100644 index 9e55dbd..0000000 --- a/OnLive/src/main/java/com/frank/living/listener/OnDoubleClickListener.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.frank.living.listener; - -import android.view.MotionEvent; -import android.view.View; - -/** - * double click listener - * Created by xufulong on 2019/2/27. - */ - -public class OnDoubleClickListener implements View.OnTouchListener { - - private final static long DOUBLE_TIME = 500; - private long firstClick; - private long secondClick; - private int clickCount; - - private OnDoubleClick onDoubleClick; - - public OnDoubleClickListener(OnDoubleClick onDoubleClick) { - this.onDoubleClick = onDoubleClick; - } - - public interface OnDoubleClick { - void onDouble(); - } - - @Override - public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_UP) { - return v.performClick(); - } else if (event.getAction() == MotionEvent.ACTION_DOWN) { - clickCount++; - if (clickCount == 1) { - firstClick = System.currentTimeMillis(); - } else if (clickCount == 2) { - secondClick = System.currentTimeMillis(); - if (secondClick - firstClick <= DOUBLE_TIME) { - firstClick = 0; - clickCount = 1; - if (onDoubleClick != null) { - onDoubleClick.onDouble(); - } - } else { - firstClick = secondClick; - clickCount = 1; - } - secondClick = 0; - } else { - clickCount = 0; - firstClick = 0; - secondClick = 0; - } - } - - return false; - } - -} diff --git a/OnLive/src/main/java/com/frank/living/util/PhotoUtil.java b/OnLive/src/main/java/com/frank/living/util/PhotoUtil.java deleted file mode 100644 index e9aafca..0000000 --- a/OnLive/src/main/java/com/frank/living/util/PhotoUtil.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.frank.living.util; - -import android.content.Context; -import android.graphics.Bitmap; -import android.os.Looper; -import android.text.TextUtils; -import android.widget.Toast; - -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * the tool of photo - * Created by frank on 2019/12/31 - */ - -public class PhotoUtil { - - public static void savePhoto(Bitmap bitmap, String path, Context context) { - savePhoto(bitmap, path, context, 100); - } - - public static void savePhoto(Bitmap bitmap, String path, Context context, int quality) { - if (bitmap == null || TextUtils.isEmpty(path) || context == null) { - return; - } - if (quality <= 0 || quality > 100) { - quality = 100; - } - FileOutputStream fileOutputStream = null; - try { - fileOutputStream = new FileOutputStream(path); - bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fileOutputStream); - fileOutputStream.flush(); - if (Looper.myLooper() == Looper.getMainLooper()) { - Toast.makeText(context.getApplicationContext(), "save success:" + path, Toast.LENGTH_SHORT).show(); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (fileOutputStream != null) { - try { - fileOutputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - -} diff --git a/OnLive/src/main/java/com/frank/living/widget/AndroidMediaController.java b/OnLive/src/main/java/com/frank/living/widget/AndroidMediaController.java deleted file mode 100644 index 0971510..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/AndroidMediaController.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import android.content.Context; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; -import android.util.AttributeSet; -import android.view.View; -import android.widget.MediaController; - -import java.util.ArrayList; - -public class AndroidMediaController extends MediaController implements IMediaController { - private ActionBar mActionBar; - - public AndroidMediaController(Context context, AttributeSet attrs) { - super(context, attrs); - initView(context); - } - - public AndroidMediaController(Context context, boolean useFastForward) { - super(context, useFastForward); - initView(context); - } - - public AndroidMediaController(Context context) { - super(context); - initView(context); - } - - private void initView(Context context) { - } - - public void setSupportActionBar(@Nullable ActionBar actionBar) { - mActionBar = actionBar; - if (isShowing()) { - actionBar.show(); - } else { - actionBar.hide(); - } - } - - @Override - public void show() { - super.show(); - if (mActionBar != null) - mActionBar.show(); - } - - @Override - public void hide() { - super.hide(); - if (mActionBar != null) - mActionBar.hide(); - for (View view : mShowOnceArray) - view.setVisibility(View.GONE); - mShowOnceArray.clear(); - } - - //---------- - // Extends - //---------- - private ArrayList mShowOnceArray = new ArrayList(); - - public void showOnce(@NonNull View view) { - mShowOnceArray.add(view); - view.setVisibility(View.VISIBLE); - show(); - } -} diff --git a/OnLive/src/main/java/com/frank/living/widget/FileMediaDataSource.java b/OnLive/src/main/java/com/frank/living/widget/FileMediaDataSource.java deleted file mode 100644 index ef364bc..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/FileMediaDataSource.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; - -import tv.danmaku.ijk.media.player.misc.IMediaDataSource; - -public class FileMediaDataSource implements IMediaDataSource { - private RandomAccessFile mFile; - private long mFileSize; - - public FileMediaDataSource(File file) throws IOException { - mFile = new RandomAccessFile(file, "r"); - mFileSize = mFile.length(); - } - - @Override - public int readAt(long position, byte[] buffer, int offset, int size) throws IOException { - if (mFile.getFilePointer() != position) - mFile.seek(position); - - if (size == 0) - return 0; - - return mFile.read(buffer, 0, size); - } - - @Override - public long getSize() throws IOException { - return mFileSize; - } - - @Override - public void close() throws IOException { - mFileSize = 0; - mFile.close(); - mFile = null; - } -} diff --git a/OnLive/src/main/java/com/frank/living/widget/IMediaController.java b/OnLive/src/main/java/com/frank/living/widget/IMediaController.java deleted file mode 100644 index 637fa6d..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/IMediaController.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import android.view.View; -import android.widget.MediaController; - -public interface IMediaController { - void hide(); - - boolean isShowing(); - - void setAnchorView(View view); - - void setEnabled(boolean enabled); - - void setMediaPlayer(MediaController.MediaPlayerControl player); - - void show(int timeout); - - void show(); - - //---------- - // Extends - //---------- - void showOnce(View view); -} diff --git a/OnLive/src/main/java/com/frank/living/widget/IRenderView.java b/OnLive/src/main/java/com/frank/living/widget/IRenderView.java deleted file mode 100644 index 694dcfb..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/IRenderView.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import android.graphics.SurfaceTexture; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.View; - -import tv.danmaku.ijk.media.player.IMediaPlayer; - -public interface IRenderView { - int AR_ASPECT_FIT_PARENT = 0; // without clip - int AR_ASPECT_FILL_PARENT = 1; // may clip - int AR_ASPECT_WRAP_CONTENT = 2; - int AR_MATCH_PARENT = 3; - int AR_16_9_FIT_PARENT = 4; - int AR_4_3_FIT_PARENT = 5; - - View getView(); - - boolean shouldWaitForResize(); - - void setVideoSize(int videoWidth, int videoHeight); - - void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen); - - void setVideoRotation(int degree); - - void setAspectRatio(int aspectRatio); - - void addRenderCallback(@NonNull IRenderCallback callback); - - void removeRenderCallback(@NonNull IRenderCallback callback); - - interface ISurfaceHolder { - void bindToMediaPlayer(IMediaPlayer mp); - - @NonNull - IRenderView getRenderView(); - - @Nullable - SurfaceHolder getSurfaceHolder(); - - @Nullable - Surface openSurface(); - - @Nullable - SurfaceTexture getSurfaceTexture(); - } - - interface IRenderCallback { - /** - * @param holder - * @param width could be 0 - * @param height could be 0 - */ - void onSurfaceCreated(@NonNull ISurfaceHolder holder, int width, int height); - - /** - * @param holder - * @param format could be 0 - * @param width - * @param height - */ - void onSurfaceChanged(@NonNull ISurfaceHolder holder, int format, int width, int height); - - void onSurfaceDestroyed(@NonNull ISurfaceHolder holder); - } -} diff --git a/OnLive/src/main/java/com/frank/living/widget/IjkVideoView.java b/OnLive/src/main/java/com/frank/living/widget/IjkVideoView.java deleted file mode 100644 index 68f1b01..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/IjkVideoView.java +++ /dev/null @@ -1,1205 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.DialogInterface; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.media.AudioManager; -import android.media.MediaPlayer; -import android.net.Uri; -import android.os.Build; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.MediaController; -import android.widget.TableLayout; -import android.widget.TextView; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import com.frank.living.listener.IjkPlayerListener; -import tv.danmaku.ijk.media.exo.IjkExoMediaPlayer; -import tv.danmaku.ijk.media.player.AndroidMediaPlayer; -import tv.danmaku.ijk.media.player.IMediaPlayer; -import tv.danmaku.ijk.media.player.IjkMediaPlayer; -import tv.danmaku.ijk.media.player.IjkTimedText; -import tv.danmaku.ijk.media.player.TextureMediaPlayer; -import tv.danmaku.ijk.media.player.misc.IMediaDataSource; -import tv.danmaku.ijk.media.player.misc.IMediaFormat; -import tv.danmaku.ijk.media.player.misc.ITrackInfo; -import tv.danmaku.ijk.media.player.misc.IjkMediaFormat; -import com.frank.living.R; -import com.frank.living.config.Settings; - -public class IjkVideoView extends FrameLayout implements MediaController.MediaPlayerControl { - private String TAG = "IjkVideoView"; - // settable by the client - private Uri mUri; - private Map mHeaders; - - // all possible internal states - private static final int STATE_ERROR = -1; - private static final int STATE_IDLE = 0; - private static final int STATE_PREPARING = 1; - private static final int STATE_PREPARED = 2; - private static final int STATE_PLAYING = 3; - private static final int STATE_PAUSED = 4; - private static final int STATE_PLAYBACK_COMPLETED = 5; - - // mCurrentState is a VideoView object's current state. - // mTargetState is the state that a method caller intends to reach. - // For instance, regardless the VideoView object's current state, - // calling pause() intends to bring the object to a target state - // of STATE_PAUSED. - private int mCurrentState = STATE_IDLE; - private int mTargetState = STATE_IDLE; - - // All the stuff we need for playing and showing a video - private IRenderView.ISurfaceHolder mSurfaceHolder = null; - private IMediaPlayer mMediaPlayer = null; - // private int mAudioSession; - private int mVideoWidth; - private int mVideoHeight; - private int mSurfaceWidth; - private int mSurfaceHeight; - private int mVideoRotationDegree; - private IMediaController mMediaController; - private IMediaPlayer.OnCompletionListener mOnCompletionListener; - private IMediaPlayer.OnPreparedListener mOnPreparedListener; - private int mCurrentBufferPercentage; - private IMediaPlayer.OnErrorListener mOnErrorListener; - private IMediaPlayer.OnInfoListener mOnInfoListener; - private int mSeekWhenPrepared; // recording the seek position while preparing - private boolean mCanPause = true; - private boolean mCanSeekBack = true; - private boolean mCanSeekForward = true; - - private Context mAppContext; - private Settings mSettings; - private IRenderView mRenderView; - private int mVideoSarNum; - private int mVideoSarDen; - - private InfoHudViewHolder mHudViewHolder; - - private long mPrepareStartTime = 0; - private long mPrepareEndTime = 0; - - private long mSeekStartTime = 0; - private long mSeekEndTime = 0; - - private TextView subtitleDisplay; - - private IjkPlayerListener ijkPlayerListener; - - public IjkVideoView(Context context) { - super(context); - initVideoView(context); - } - - public IjkVideoView(Context context, AttributeSet attrs) { - super(context, attrs); - initVideoView(context); - } - - public IjkVideoView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initVideoView(context); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public IjkVideoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - initVideoView(context); - } - - private void initVideoView(Context context) { - mAppContext = context.getApplicationContext(); - mSettings = new Settings(mAppContext); - initRenders(); - - mVideoWidth = 0; - mVideoHeight = 0; - setFocusable(true); - setFocusableInTouchMode(true); - requestFocus(); - mCurrentState = STATE_IDLE; - mTargetState = STATE_IDLE; - - subtitleDisplay = new TextView(context); - subtitleDisplay.setTextSize(24); - subtitleDisplay.setGravity(Gravity.CENTER); - FrameLayout.LayoutParams layoutParams_txt = new FrameLayout.LayoutParams( - FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.WRAP_CONTENT, - Gravity.BOTTOM); - addView(subtitleDisplay, layoutParams_txt); - } - - public void setRenderView(IRenderView renderView) { - if (mRenderView != null) { - if (mMediaPlayer != null) - mMediaPlayer.setDisplay(null); - - View renderUIView = mRenderView.getView(); - mRenderView.removeRenderCallback(mSHCallback); - mRenderView = null; - removeView(renderUIView); - } - - if (renderView == null) - return; - - mRenderView = renderView; - renderView.setAspectRatio(mCurrentAspectRatio); - if (mVideoWidth > 0 && mVideoHeight > 0) - renderView.setVideoSize(mVideoWidth, mVideoHeight); - if (mVideoSarNum > 0 && mVideoSarDen > 0) - renderView.setVideoSampleAspectRatio(mVideoSarNum, mVideoSarDen); - - View renderUIView = mRenderView.getView(); - FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT, - Gravity.CENTER); - renderUIView.setLayoutParams(lp); - addView(renderUIView); - - mRenderView.addRenderCallback(mSHCallback); - if (mVideoRotationDegree > 0){ - mRenderView.setVideoRotation(mVideoRotationDegree); - } - } - - public void setRender(int render) { - switch (render) { - case RENDER_NONE: - setRenderView(null); - break; - case RENDER_TEXTURE_VIEW: { - TextureRenderView renderView = new TextureRenderView(getContext()); - if (mMediaPlayer != null) { - renderView.getSurfaceHolder().bindToMediaPlayer(mMediaPlayer); - renderView.setVideoSize(mMediaPlayer.getVideoWidth(), mMediaPlayer.getVideoHeight()); - renderView.setVideoSampleAspectRatio(mMediaPlayer.getVideoSarNum(), mMediaPlayer.getVideoSarDen()); - renderView.setAspectRatio(mCurrentAspectRatio); - } - setRenderView(renderView); - break; - } - case RENDER_SURFACE_VIEW: { - SurfaceRenderView renderView = new SurfaceRenderView(getContext()); - setRenderView(renderView); - break; - } - default: - Log.e(TAG, String.format(Locale.getDefault(), "invalid render %d\n", render)); - break; - } - } - - public void setHudView(TableLayout tableLayout) { - mHudViewHolder = new InfoHudViewHolder(getContext(), tableLayout); - } - - public void setIjkPlayerListener(IjkPlayerListener ijkPlayerListener){ - this.ijkPlayerListener = ijkPlayerListener; - } - - /** - * Sets video path. - * - * @param path the path of the video. - */ - public void setVideoPath(String path) { - setVideoURI(Uri.parse(path)); - } - - /** - * Sets video URI. - * - * @param uri the URI of the video. - */ - public void setVideoURI(Uri uri) { - setVideoURI(uri, null); - } - - /** - * Sets video URI using specific headers. - * - * @param uri the URI of the video. - * @param headers the headers for the URI request. - * Note that the cross domain redirection is allowed by default, but that can be - * changed with key/value pairs through the headers parameter with - * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value - * to disallow or allow cross domain redirection. - */ - private void setVideoURI(Uri uri, Map headers) { - mUri = uri; - mHeaders = headers; - mSeekWhenPrepared = 0; - openVideo(); - requestLayout(); - invalidate(); - } - - public void stopPlayback() { - if (mMediaPlayer != null) { - mMediaPlayer.stop(); - mMediaPlayer.release(); - mMediaPlayer = null; - if (mHudViewHolder != null) - mHudViewHolder.setMediaPlayer(null); - mCurrentState = STATE_IDLE; - mTargetState = STATE_IDLE; - AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE); - am.abandonAudioFocus(null); - } - } - - @TargetApi(Build.VERSION_CODES.M) - private void openVideo() { - if (mUri == null || mSurfaceHolder == null) { - // not ready for playback just yet, will try again later - return; - } - // we shouldn't clear the target state, because somebody might have - // called start() previously - release(false); - - AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE); - am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); - - try { - mMediaPlayer = createPlayer(mSettings.getPlayer()); - - // REMOVED: mAudioSession - mMediaPlayer.setOnPreparedListener(mPreparedListener); - mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener); - mMediaPlayer.setOnCompletionListener(mCompletionListener); - mMediaPlayer.setOnErrorListener(mErrorListener); - mMediaPlayer.setOnInfoListener(mInfoListener); - mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener); - mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener); - mMediaPlayer.setOnTimedTextListener(mOnTimedTextListener); - mCurrentBufferPercentage = 0; - String scheme = mUri.getScheme(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && - mSettings.getUsingMediaDataSource() && - (TextUtils.isEmpty(scheme) || scheme.equalsIgnoreCase("file"))) { - IMediaDataSource dataSource = new FileMediaDataSource(new File(mUri.toString())); - mMediaPlayer.setDataSource(dataSource); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - mMediaPlayer.setDataSource(mAppContext, mUri, mHeaders); - } else { - mMediaPlayer.setDataSource(mUri.toString()); - } - bindSurfaceHolder(mMediaPlayer, mSurfaceHolder); - mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); - mMediaPlayer.setScreenOnWhilePlaying(true); - mPrepareStartTime = System.currentTimeMillis(); - mMediaPlayer.prepareAsync(); - if (mHudViewHolder != null) - mHudViewHolder.setMediaPlayer(mMediaPlayer); - - // REMOVED: mPendingSubtitleTracks - - // we don't set the target state here either, but preserve the - // target state that was there before. - mCurrentState = STATE_PREPARING; - attachMediaController(); - } catch (IOException | IllegalArgumentException ex) { - Log.w(TAG, "Unable to open content: " + mUri, ex); - mCurrentState = STATE_ERROR; - mTargetState = STATE_ERROR; - mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0); - } finally { - // REMOVED: mPendingSubtitleTracks.clear(); - } - } - - public void setMediaController(IMediaController controller) { - if (mMediaController != null) { - mMediaController.hide(); - } - mMediaController = controller; - attachMediaController(); - } - - private void attachMediaController() { - if (mMediaPlayer != null && mMediaController != null) { - mMediaController.setMediaPlayer(this); - View anchorView = this.getParent() instanceof View ? - (View) this.getParent() : this; - mMediaController.setAnchorView(anchorView); - mMediaController.setEnabled(isInPlaybackState()); - } - } - - IMediaPlayer.OnVideoSizeChangedListener mSizeChangedListener = - new IMediaPlayer.OnVideoSizeChangedListener() { - public void onVideoSizeChanged(IMediaPlayer mp, int width, int height, int sarNum, int sarDen) { - mVideoWidth = mp.getVideoWidth(); - mVideoHeight = mp.getVideoHeight(); - mVideoSarNum = mp.getVideoSarNum(); - mVideoSarDen = mp.getVideoSarDen(); - if (mVideoWidth != 0 && mVideoHeight != 0) { - if (mRenderView != null) { - mRenderView.setVideoSize(mVideoWidth, mVideoHeight); - mRenderView.setVideoSampleAspectRatio(mVideoSarNum, mVideoSarDen); - } - // REMOVED: getHolder().setFixedSize(mVideoWidth, mVideoHeight); - requestLayout(); - } - } - }; - - IMediaPlayer.OnPreparedListener mPreparedListener = new IMediaPlayer.OnPreparedListener() { - public void onPrepared(IMediaPlayer mp) { - mPrepareEndTime = System.currentTimeMillis(); - if (mHudViewHolder != null){ - mHudViewHolder.updateLoadCost(mPrepareEndTime - mPrepareStartTime); - } - mCurrentState = STATE_PREPARED; - - // Get the capabilities of the player for this stream - // REMOVED: Metadata - - if (mOnPreparedListener != null) { - mOnPreparedListener.onPrepared(mMediaPlayer); - } - if (mMediaController != null) { - mMediaController.setEnabled(true); - } - mVideoWidth = mp.getVideoWidth(); - mVideoHeight = mp.getVideoHeight(); - - int seekToPosition = mSeekWhenPrepared; // mSeekWhenPrepared may be changed after seekTo() call - if (seekToPosition != 0) { - seekTo(seekToPosition); - } - if (mVideoWidth != 0 && mVideoHeight != 0) { - //Log.i("@@@@", "video size: " + mVideoWidth +"/"+ mVideoHeight); - // REMOVED: getHolder().setFixedSize(mVideoWidth, mVideoHeight); - if (mRenderView != null) { - mRenderView.setVideoSize(mVideoWidth, mVideoHeight); - mRenderView.setVideoSampleAspectRatio(mVideoSarNum, mVideoSarDen); - if (!mRenderView.shouldWaitForResize() || mSurfaceWidth == mVideoWidth && mSurfaceHeight == mVideoHeight) { - // We didn't actually change the size (it was already at the size - // we need), so we won't get a "surface changed" callback, so - // start the video here instead of in the callback. - if (mTargetState == STATE_PLAYING) { - start(); - if (mMediaController != null) { - mMediaController.show(); - } - } else if (!isPlaying() && - (seekToPosition != 0 || getCurrentPosition() > 0)) { - if (mMediaController != null) { - // Show the media controls when we're paused into a video and make 'em stick. - mMediaController.show(0); - } - } - } - } - } else { - // We don't know the video size yet, but should start anyway. - // The video size might be reported to us later. - if (mTargetState == STATE_PLAYING) { - start(); - } - } - } - }; - - private IMediaPlayer.OnCompletionListener mCompletionListener = - new IMediaPlayer.OnCompletionListener() { - public void onCompletion(IMediaPlayer mp) { - mCurrentState = STATE_PLAYBACK_COMPLETED; - mTargetState = STATE_PLAYBACK_COMPLETED; - if (mMediaController != null) { - mMediaController.hide(); - } - if (mOnCompletionListener != null) { - mOnCompletionListener.onCompletion(mMediaPlayer); - } - } - }; - - private IMediaPlayer.OnInfoListener mInfoListener = - new IMediaPlayer.OnInfoListener() { - public boolean onInfo(IMediaPlayer mp, int arg1, int arg2) { - if (mOnInfoListener != null) { - mOnInfoListener.onInfo(mp, arg1, arg2); - } - switch (arg1) { - case IMediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING: - Log.d(TAG, "MEDIA_INFO_VIDEO_TRACK_LAGGING:"); - break; - case IMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: - Log.d(TAG, "MEDIA_INFO_VIDEO_RENDERING_START:"); - break; - case IMediaPlayer.MEDIA_INFO_BUFFERING_START: - Log.d(TAG, "MEDIA_INFO_BUFFERING_START:"); - break; - case IMediaPlayer.MEDIA_INFO_BUFFERING_END: - Log.d(TAG, "MEDIA_INFO_BUFFERING_END:"); - break; - case IMediaPlayer.MEDIA_INFO_NETWORK_BANDWIDTH: - Log.d(TAG, "MEDIA_INFO_NETWORK_BANDWIDTH: " + arg2); - break; - case IMediaPlayer.MEDIA_INFO_BAD_INTERLEAVING: - Log.d(TAG, "MEDIA_INFO_BAD_INTERLEAVING:"); - break; - case IMediaPlayer.MEDIA_INFO_NOT_SEEKABLE: - Log.d(TAG, "MEDIA_INFO_NOT_SEEKABLE:"); - break; - case IMediaPlayer.MEDIA_INFO_METADATA_UPDATE: - Log.d(TAG, "MEDIA_INFO_METADATA_UPDATE:"); - break; - case IMediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE: - Log.d(TAG, "MEDIA_INFO_UNSUPPORTED_SUBTITLE:"); - break; - case IMediaPlayer.MEDIA_INFO_SUBTITLE_TIMED_OUT: - Log.d(TAG, "MEDIA_INFO_SUBTITLE_TIMED_OUT:"); - break; - case IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED: - mVideoRotationDegree = arg2; - Log.d(TAG, "MEDIA_INFO_VIDEO_ROTATION_CHANGED: " + arg2); - if (mRenderView != null && arg2 > 0) - mRenderView.setVideoRotation(arg2); - break; - case IMediaPlayer.MEDIA_INFO_AUDIO_RENDERING_START: - Log.d(TAG, "MEDIA_INFO_AUDIO_RENDERING_START:"); - break; - } - return true; - } - }; - - private IMediaPlayer.OnErrorListener mErrorListener = - new IMediaPlayer.OnErrorListener() { - public boolean onError(IMediaPlayer mp, int framework_err, int impl_err) { - Log.d(TAG, "Error: " + framework_err + "," + impl_err); - mCurrentState = STATE_ERROR; - mTargetState = STATE_ERROR; - if (mMediaController != null) { - mMediaController.hide(); - } - - /* If an error handler has been supplied, use it and finish. */ - if (mOnErrorListener != null) { - if (mOnErrorListener.onError(mMediaPlayer, framework_err, impl_err)) { - return true; - } - } - - /* Otherwise, pop up an error dialog so the user knows that - * something bad has happened. Only try and pop up the dialog - * if we're attached to a window. When we're going away and no - * longer have a window, don't bother showing the user an error. - */ - if (getWindowToken() != null) { - Resources r = mAppContext.getResources(); - int messageId; - - if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) { - messageId = R.string.VideoView_error_text_invalid_progressive_playback; - } else { - messageId = R.string.VideoView_error_text_unknown; - } - - new AlertDialog.Builder(getContext()) - .setMessage(messageId) - .setPositiveButton(R.string.VideoView_error_button, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - /* If we get here, there is no onError listener, so - * at least inform them that the video is over. - */ - if (mOnCompletionListener != null) { - mOnCompletionListener.onCompletion(mMediaPlayer); - } - } - }) - .setCancelable(false) - .show(); - } - return true; - } - }; - - private IMediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = - new IMediaPlayer.OnBufferingUpdateListener() { - public void onBufferingUpdate(IMediaPlayer mp, int percent) { - mCurrentBufferPercentage = percent; - } - }; - - private IMediaPlayer.OnSeekCompleteListener mSeekCompleteListener = new IMediaPlayer.OnSeekCompleteListener() { - - @Override - public void onSeekComplete(IMediaPlayer mp) { - mSeekEndTime = System.currentTimeMillis(); - mHudViewHolder.updateSeekCost(mSeekEndTime - mSeekStartTime); - } - }; - - private IMediaPlayer.OnTimedTextListener mOnTimedTextListener = new IMediaPlayer.OnTimedTextListener() { - @Override - public void onTimedText(IMediaPlayer mp, IjkTimedText text) { - if (text != null) { - subtitleDisplay.setText(text.getText()); - } - } - }; - - /** - * Register a callback to be invoked when the media file - * is loaded and ready to go. - * - * @param l The callback that will be run - */ - public void setOnPreparedListener(IMediaPlayer.OnPreparedListener l) { - mOnPreparedListener = l; - } - - /** - * Register a callback to be invoked when the end of a media file - * has been reached during playback. - * - * @param l The callback that will be run - */ - public void setOnCompletionListener(IMediaPlayer.OnCompletionListener l) { - mOnCompletionListener = l; - } - - /** - * Register a callback to be invoked when an error occurs - * during playback or setup. If no listener is specified, - * or if the listener returned false, VideoView will inform - * the user of any errors. - * - * @param l The callback that will be run - */ - public void setOnErrorListener(IMediaPlayer.OnErrorListener l) { - mOnErrorListener = l; - } - - /** - * Register a callback to be invoked when an informational event - * occurs during playback or setup. - * - * @param l The callback that will be run - */ - public void setOnInfoListener(IMediaPlayer.OnInfoListener l) { - mOnInfoListener = l; - } - - // REMOVED: mSHCallback - private void bindSurfaceHolder(IMediaPlayer mp, IRenderView.ISurfaceHolder holder) { - if (mp == null) - return; - - if (holder == null) { - mp.setDisplay(null); - return; - } - - holder.bindToMediaPlayer(mp); - } - - IRenderView.IRenderCallback mSHCallback = new IRenderView.IRenderCallback() { - @Override - public void onSurfaceChanged(@NonNull IRenderView.ISurfaceHolder holder, int format, int w, int h) { - if (holder.getRenderView() != mRenderView) { - Log.e(TAG, "onSurfaceChanged: unmatched render callback\n"); - return; - } - - mSurfaceWidth = w; - mSurfaceHeight = h; - boolean isValidState = (mTargetState == STATE_PLAYING); - boolean hasValidSize = !mRenderView.shouldWaitForResize() || (mVideoWidth == w && mVideoHeight == h); - if (mMediaPlayer != null && isValidState && hasValidSize) { - if (mSeekWhenPrepared != 0) { - seekTo(mSeekWhenPrepared); - } - start(); - } - } - - @Override - public void onSurfaceCreated(@NonNull IRenderView.ISurfaceHolder holder, int width, int height) { - if (holder.getRenderView() != mRenderView) { - Log.e(TAG, "onSurfaceCreated: unmatched render callback\n"); - return; - } - - mSurfaceHolder = holder; - if (mMediaPlayer != null) - bindSurfaceHolder(mMediaPlayer, holder); - else - openVideo(); - } - - @Override - public void onSurfaceDestroyed(@NonNull IRenderView.ISurfaceHolder holder) { - if (holder.getRenderView() != mRenderView) { - Log.e(TAG, "onSurfaceDestroyed: unmatched render callback\n"); - return; - } - - // after we return from this we can't use the surface any more - mSurfaceHolder = null; - // REMOVED: if (mMediaController != null) mMediaController.hide(); - // REMOVED: release(true); - releaseWithoutStop(); - } - }; - - public void releaseWithoutStop() { - if (mMediaPlayer != null) - mMediaPlayer.setDisplay(null); - } - - /* - * release the media player in any state - */ - public void release(boolean cleartargetstate) { - if (mMediaPlayer != null) { - mMediaPlayer.reset(); - mMediaPlayer.release(); - mMediaPlayer = null; - // REMOVED: mPendingSubtitleTracks.clear(); - mCurrentState = STATE_IDLE; - if (cleartargetstate) { - mTargetState = STATE_IDLE; - } - AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE); - am.abandonAudioFocus(null); - } - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - if (isInPlaybackState() && mMediaController != null) { - toggleMediaControlsVisiblity(); - } - return false; - } - - @Override - public boolean onTrackballEvent(MotionEvent ev) { - if (isInPlaybackState() && mMediaController != null) { - toggleMediaControlsVisiblity(); - } - return false; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - boolean isKeyCodeSupported = keyCode != KeyEvent.KEYCODE_BACK && - keyCode != KeyEvent.KEYCODE_VOLUME_UP && - keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && - keyCode != KeyEvent.KEYCODE_VOLUME_MUTE && - keyCode != KeyEvent.KEYCODE_MENU && - keyCode != KeyEvent.KEYCODE_CALL && - keyCode != KeyEvent.KEYCODE_ENDCALL; - if (isInPlaybackState() && isKeyCodeSupported && mMediaController != null) { - if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK || - keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) { - if (mMediaPlayer.isPlaying()) { - pause(); - mMediaController.show(); - } else { - start(); - mMediaController.hide(); - } - return true; - } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) { - if (!mMediaPlayer.isPlaying()) { - start(); - mMediaController.hide(); - } - return true; - } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP - || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) { - if (mMediaPlayer.isPlaying()) { - pause(); - mMediaController.show(); - } - return true; - } else { - toggleMediaControlsVisiblity(); - } - } - - return super.onKeyDown(keyCode, event); - } - - private void toggleMediaControlsVisiblity() { - if (mMediaController.isShowing()) { - mMediaController.hide(); - } else { - mMediaController.show(); - } - } - - @Override - public void start() { - if (isInPlaybackState()) { - mMediaPlayer.start(); - mCurrentState = STATE_PLAYING; - } - mTargetState = STATE_PLAYING; - } - - @Override - public void pause() { - if (isInPlaybackState()) { - if (mMediaPlayer.isPlaying()) { - mMediaPlayer.pause(); - mCurrentState = STATE_PAUSED; - } - } - mTargetState = STATE_PAUSED; - } - - public void suspend() { - release(false); - } - - public void resume() { - openVideo(); - } - - @Override - public int getDuration() { - if (isInPlaybackState()) { - return (int) mMediaPlayer.getDuration(); - } - - return -1; - } - - @Override - public int getCurrentPosition() { - if (isInPlaybackState()) { - return (int) mMediaPlayer.getCurrentPosition(); - } - return 0; - } - - @Override - public void seekTo(int msec) { - if (isInPlaybackState()) { - mSeekStartTime = System.currentTimeMillis(); - mMediaPlayer.seekTo(msec); - mSeekWhenPrepared = 0; - } else { - mSeekWhenPrepared = msec; - } - } - - @Override - public boolean isPlaying() { - return isInPlaybackState() && mMediaPlayer.isPlaying(); - } - - @Override - public int getBufferPercentage() { - if (mMediaPlayer != null) { - return mCurrentBufferPercentage; - } - return 0; - } - - private boolean isInPlaybackState() { - return (mMediaPlayer != null && - mCurrentState != STATE_ERROR && - mCurrentState != STATE_IDLE && - mCurrentState != STATE_PREPARING); - } - - @Override - public boolean canPause() { - return mCanPause; - } - - @Override - public boolean canSeekBackward() { - return mCanSeekBack; - } - - @Override - public boolean canSeekForward() { - return mCanSeekForward; - } - - @Override - public int getAudioSessionId() { - return 0; - } - - //------------------------- - // Extend: Aspect Ratio - //------------------------- - - private static final int[] s_allAspectRatio = { - IRenderView.AR_ASPECT_FIT_PARENT, - IRenderView.AR_ASPECT_FILL_PARENT, - IRenderView.AR_ASPECT_WRAP_CONTENT, - // IRenderView.AR_MATCH_PARENT, - IRenderView.AR_16_9_FIT_PARENT, - IRenderView.AR_4_3_FIT_PARENT}; - private int mCurrentAspectRatioIndex = 0; - private int mCurrentAspectRatio = s_allAspectRatio[0]; - - public int toggleAspectRatio() { - mCurrentAspectRatioIndex++; - mCurrentAspectRatioIndex %= s_allAspectRatio.length; - - mCurrentAspectRatio = s_allAspectRatio[mCurrentAspectRatioIndex]; - if (mRenderView != null) - mRenderView.setAspectRatio(mCurrentAspectRatio); - return mCurrentAspectRatio; - } - - //------------------------- - // Extend: Render - //------------------------- - public static final int RENDER_NONE = 0; - public static final int RENDER_SURFACE_VIEW = 1; - public static final int RENDER_TEXTURE_VIEW = 2; - - private List mAllRenders = new ArrayList<>(); - private int mCurrentRenderIndex = 0; - private int mCurrentRender = RENDER_NONE; - - private void initRenders() { - mAllRenders.clear(); - - if (mSettings.getEnableSurfaceView()) - mAllRenders.add(RENDER_SURFACE_VIEW); - if (mSettings.getEnableTextureView() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) - mAllRenders.add(RENDER_TEXTURE_VIEW); - if (mSettings.getEnableNoView()) - mAllRenders.add(RENDER_NONE); - - if (mAllRenders.isEmpty()) - mAllRenders.add(RENDER_SURFACE_VIEW); - mCurrentRender = mAllRenders.get(mCurrentRenderIndex); - setRender(mCurrentRender); - } - - public int toggleRender() { - mCurrentRenderIndex++; - mCurrentRenderIndex %= mAllRenders.size(); - - mCurrentRender = mAllRenders.get(mCurrentRenderIndex); - setRender(mCurrentRender); - return mCurrentRender; - } - - @NonNull - public static String getRenderText(Context context, int render) { - String text; - switch (render) { - case RENDER_NONE: - text = context.getString(R.string.VideoView_render_none); - break; - case RENDER_SURFACE_VIEW: - text = context.getString(R.string.VideoView_render_surface_view); - break; - case RENDER_TEXTURE_VIEW: - text = context.getString(R.string.VideoView_render_texture_view); - break; - default: - text = context.getString(R.string.N_A); - break; - } - return text; - } - - //------------------------- - // Extend: Player - //------------------------- - public int togglePlayer() { - if (mMediaPlayer != null) - mMediaPlayer.release(); - - if (mRenderView != null) - mRenderView.getView().invalidate(); - openVideo(); - return mSettings.getPlayer(); - } - - @NonNull - public static String getPlayerText(Context context, int player) { - String text; - switch (player) { - case Settings.PV_PLAYER__AndroidMediaPlayer: - text = context.getString(R.string.VideoView_player_AndroidMediaPlayer); - break; - case Settings.PV_PLAYER__IjkMediaPlayer: - text = context.getString(R.string.VideoView_player_IjkMediaPlayer); - break; - case Settings.PV_PLAYER__IjkExoMediaPlayer: - text = context.getString(R.string.VideoView_player_IjkExoMediaPlayer); - break; - default: - text = context.getString(R.string.N_A); - break; - } - return text; - } - - public IMediaPlayer createPlayer(int playerType) { - IMediaPlayer mediaPlayer; - switch (playerType) { - case Settings.PV_PLAYER__IjkExoMediaPlayer: { - mediaPlayer = new IjkExoMediaPlayer(mAppContext); - } - break; - case Settings.PV_PLAYER__AndroidMediaPlayer: { - mediaPlayer = new AndroidMediaPlayer(); - } - break; - case Settings.PV_PLAYER__IjkMediaPlayer: - default: { - IjkMediaPlayer ijkMediaPlayer = null; - if (mUri != null) { - ijkMediaPlayer = new IjkMediaPlayer(); - ijkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_INFO); - - if (mSettings.getUsingMediaCodec()) { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1); - if (mSettings.getUsingMediaCodecAutoRotate()) { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1); - } else { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 0); - } - if (mSettings.getMediaCodecHandleResolutionChange()) { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1); - } else { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 0); - } - } else { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0); - } - - if (mSettings.getUsingOpenSLES()) { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 1); - } else { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 0); - } - - String pixelFormat = mSettings.getPixelFormat(); - if (TextUtils.isEmpty(pixelFormat)) { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32); - } else { - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", pixelFormat); - } - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1); - - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0); - - ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48); - } - mediaPlayer = ijkMediaPlayer; - if (ijkPlayerListener != null){ - ijkPlayerListener.onIjkPlayer(ijkMediaPlayer); - } - } - break; - } - - if (mSettings.getEnableDetachedSurfaceTextureView()) { - mediaPlayer = new TextureMediaPlayer(mediaPlayer); - } - - return mediaPlayer; - } - - //------------------------- - // Extend: Background - //------------------------- - public void showMediaInfo() { - if (mMediaPlayer == null) - return; - - int selectedVideoTrack = MediaPlayerCompat.getSelectedTrack(mMediaPlayer, ITrackInfo.MEDIA_TRACK_TYPE_VIDEO); - int selectedAudioTrack = MediaPlayerCompat.getSelectedTrack(mMediaPlayer, ITrackInfo.MEDIA_TRACK_TYPE_AUDIO); - int selectedSubtitleTrack = MediaPlayerCompat.getSelectedTrack(mMediaPlayer, ITrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT); - - TableLayoutBinder builder = new TableLayoutBinder(getContext()); - builder.appendSection(R.string.mi_player); - builder.appendRow2(R.string.mi_player, MediaPlayerCompat.getName(mMediaPlayer)); - builder.appendSection(R.string.mi_media); - builder.appendRow2(R.string.mi_resolution, buildResolution(mVideoWidth, mVideoHeight, mVideoSarNum, mVideoSarDen)); - builder.appendRow2(R.string.mi_length, buildTimeMilli(mMediaPlayer.getDuration())); - - ITrackInfo trackInfos[] = mMediaPlayer.getTrackInfo(); - if (trackInfos != null) { - int index = -1; - for (ITrackInfo trackInfo : trackInfos) { - index++; - - int trackType = trackInfo.getTrackType(); - if (index == selectedVideoTrack) { - builder.appendSection(getContext().getString(R.string.mi_stream_fmt1, index) + " " + getContext().getString(R.string.mi__selected_video_track)); - } else if (index == selectedAudioTrack) { - builder.appendSection(getContext().getString(R.string.mi_stream_fmt1, index) + " " + getContext().getString(R.string.mi__selected_audio_track)); - } else if (index == selectedSubtitleTrack) { - builder.appendSection(getContext().getString(R.string.mi_stream_fmt1, index) + " " + getContext().getString(R.string.mi__selected_subtitle_track)); - } else { - builder.appendSection(getContext().getString(R.string.mi_stream_fmt1, index)); - } - builder.appendRow2(R.string.mi_type, buildTrackType(trackType)); - builder.appendRow2(R.string.mi_language, buildLanguage(trackInfo.getLanguage())); - - IMediaFormat mediaFormat = trackInfo.getFormat(); - if (mediaFormat == null) { - } else if (mediaFormat instanceof IjkMediaFormat) { - switch (trackType) { - case ITrackInfo.MEDIA_TRACK_TYPE_VIDEO: - builder.appendRow2(R.string.mi_codec, mediaFormat.getString(IjkMediaFormat.KEY_IJK_CODEC_LONG_NAME_UI)); - builder.appendRow2(R.string.mi_profile_level, mediaFormat.getString(IjkMediaFormat.KEY_IJK_CODEC_PROFILE_LEVEL_UI)); - builder.appendRow2(R.string.mi_pixel_format, mediaFormat.getString(IjkMediaFormat.KEY_IJK_CODEC_PIXEL_FORMAT_UI)); - builder.appendRow2(R.string.mi_resolution, mediaFormat.getString(IjkMediaFormat.KEY_IJK_RESOLUTION_UI)); - builder.appendRow2(R.string.mi_frame_rate, mediaFormat.getString(IjkMediaFormat.KEY_IJK_FRAME_RATE_UI)); - builder.appendRow2(R.string.mi_bit_rate, mediaFormat.getString(IjkMediaFormat.KEY_IJK_BIT_RATE_UI)); - break; - case ITrackInfo.MEDIA_TRACK_TYPE_AUDIO: - builder.appendRow2(R.string.mi_codec, mediaFormat.getString(IjkMediaFormat.KEY_IJK_CODEC_LONG_NAME_UI)); - builder.appendRow2(R.string.mi_profile_level, mediaFormat.getString(IjkMediaFormat.KEY_IJK_CODEC_PROFILE_LEVEL_UI)); - builder.appendRow2(R.string.mi_sample_rate, mediaFormat.getString(IjkMediaFormat.KEY_IJK_SAMPLE_RATE_UI)); - builder.appendRow2(R.string.mi_channels, mediaFormat.getString(IjkMediaFormat.KEY_IJK_CHANNEL_UI)); - builder.appendRow2(R.string.mi_bit_rate, mediaFormat.getString(IjkMediaFormat.KEY_IJK_BIT_RATE_UI)); - break; - default: - break; - } - } - } - } - - AlertDialog.Builder adBuilder = builder.buildAlertDialogBuilder(); - adBuilder.setTitle(R.string.media_information); - adBuilder.setNegativeButton(R.string.close, null); - adBuilder.show(); - } - - private String buildResolution(int width, int height, int sarNum, int sarDen) { - StringBuilder sb = new StringBuilder(); - sb.append(width); - sb.append(" x "); - sb.append(height); - - if (sarNum > 1 || sarDen > 1) { - sb.append("["); - sb.append(sarNum); - sb.append(":"); - sb.append(sarDen); - sb.append("]"); - } - - return sb.toString(); - } - - private String buildTimeMilli(long duration) { - long total_seconds = duration / 1000; - long hours = total_seconds / 3600; - long minutes = (total_seconds % 3600) / 60; - long seconds = total_seconds % 60; - if (duration <= 0) { - return "--:--"; - } - if (hours >= 100) { - return String.format(Locale.US, "%d:%02d:%02d", hours, minutes, seconds); - } else if (hours > 0) { - return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes, seconds); - } else { - return String.format(Locale.US, "%02d:%02d", minutes, seconds); - } - } - - private String buildTrackType(int type) { - Context context = getContext(); - switch (type) { - case ITrackInfo.MEDIA_TRACK_TYPE_VIDEO: - return context.getString(R.string.TrackType_video); - case ITrackInfo.MEDIA_TRACK_TYPE_AUDIO: - return context.getString(R.string.TrackType_audio); - case ITrackInfo.MEDIA_TRACK_TYPE_SUBTITLE: - return context.getString(R.string.TrackType_subtitle); - case ITrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT: - return context.getString(R.string.TrackType_timedtext); - case ITrackInfo.MEDIA_TRACK_TYPE_METADATA: - return context.getString(R.string.TrackType_metadata); - case ITrackInfo.MEDIA_TRACK_TYPE_UNKNOWN: - default: - return context.getString(R.string.TrackType_unknown); - } - } - - private String buildLanguage(String language) { - if (TextUtils.isEmpty(language)) - return "und"; - return language; - } - - @Override - public boolean performClick() { - return super.performClick(); - } - - public void setRenderViewVisible(){ - if (mRenderView != null){ - mRenderView.getView().setVisibility(VISIBLE); - } - } - - public void setRenderViewGone(){ - if (mRenderView != null){ - mRenderView.getView().setVisibility(GONE); - } - } - - public Bitmap getCurrentFrame() { - if (mRenderView instanceof TextureRenderView) { - return ((TextureRenderView) mRenderView).getBitmap(); - } - return null; - } - -} diff --git a/OnLive/src/main/java/com/frank/living/widget/InfoHudViewHolder.java b/OnLive/src/main/java/com/frank/living/widget/InfoHudViewHolder.java deleted file mode 100644 index 63ffadb..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/InfoHudViewHolder.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.frank.living.widget; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.os.Handler; -import android.os.Message; -import android.util.SparseArray; -import android.view.View; -import android.widget.TableLayout; - -import com.frank.living.R; - -import java.util.Locale; - -import tv.danmaku.ijk.media.player.IMediaPlayer; -import tv.danmaku.ijk.media.player.IjkMediaPlayer; -import tv.danmaku.ijk.media.player.MediaPlayerProxy; - -public class InfoHudViewHolder { - private TableLayoutBinder mTableLayoutBinder; - private SparseArray mRowMap = new SparseArray(); - private IMediaPlayer mMediaPlayer; - private long mLoadCost = 0; - private long mSeekCost = 0; - - public InfoHudViewHolder(Context context, TableLayout tableLayout) { - mTableLayoutBinder = new TableLayoutBinder(context, tableLayout); - } - - private void appendSection(int nameId) { - mTableLayoutBinder.appendSection(nameId); - } - - private void appendRow(int nameId) { - View rowView = mTableLayoutBinder.appendRow2(nameId, null); - mRowMap.put(nameId, rowView); - } - - private void setRowValue(int id, String value) { - View rowView = mRowMap.get(id); - if (rowView == null) { - rowView = mTableLayoutBinder.appendRow2(id, value); - mRowMap.put(id, rowView); - } else { - mTableLayoutBinder.setValueText(rowView, value); - } - } - - public void setMediaPlayer(IMediaPlayer mp) { - mMediaPlayer = mp; - if (mMediaPlayer != null) { - mHandler.sendEmptyMessageDelayed(MSG_UPDATE_HUD, 500); - } else { - mHandler.removeMessages(MSG_UPDATE_HUD); - } - } - - private static String formatedDurationMilli(long duration) { - if (duration >= 1000) { - return String.format(Locale.US, "%.2f sec", ((float)duration) / 1000); - } else { - return String.format(Locale.US, "%d msec", duration); - } - } - - private static String formatedSpeed(long bytes,long elapsed_milli) { - if (elapsed_milli <= 0) { - return "0 B/s"; - } - - if (bytes <= 0) { - return "0 B/s"; - } - - float bytes_per_sec = ((float)bytes) * 1000.f / elapsed_milli; - if (bytes_per_sec >= 1000 * 1000) { - return String.format(Locale.US, "%.2f MB/s", ((float)bytes_per_sec) / 1000 / 1000); - } else if (bytes_per_sec >= 1000) { - return String.format(Locale.US, "%.1f KB/s", ((float)bytes_per_sec) / 1000); - } else { - return String.format(Locale.US, "%d B/s", (long)bytes_per_sec); - } - } - - public void updateLoadCost(long time) { - mLoadCost = time; - } - - public void updateSeekCost(long time) { - mSeekCost = time; - } - - private static String formatedSize(long bytes) { - if (bytes >= 100 * 1000) { - return String.format(Locale.US, "%.2f MB", ((float)bytes) / 1000 / 1000); - } else if (bytes >= 100) { - return String.format(Locale.US, "%.1f KB", ((float)bytes) / 1000); - } else { - return String.format(Locale.US, "%d B", bytes); - } - } - - private static final int MSG_UPDATE_HUD = 1; - @SuppressLint("HandlerLeak") - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_UPDATE_HUD: { - InfoHudViewHolder holder = InfoHudViewHolder.this; - IjkMediaPlayer mp = null; - if (mMediaPlayer == null) - break; - if (mMediaPlayer instanceof IjkMediaPlayer) { - mp = (IjkMediaPlayer) mMediaPlayer; - } else if (mMediaPlayer instanceof MediaPlayerProxy) { - MediaPlayerProxy proxy = (MediaPlayerProxy) mMediaPlayer; - IMediaPlayer internal = proxy.getInternalMediaPlayer(); - if (internal != null && internal instanceof IjkMediaPlayer) - mp = (IjkMediaPlayer) internal; - } - if (mp == null) - break; - - int vdec = mp.getVideoDecoder(); - switch (vdec) { - case IjkMediaPlayer.FFP_PROPV_DECODER_AVCODEC: - setRowValue(R.string.vdec, "avcodec"); - break; - case IjkMediaPlayer.FFP_PROPV_DECODER_MEDIACODEC: - setRowValue(R.string.vdec, "MediaCodec"); - break; - default: - setRowValue(R.string.vdec, ""); - break; - } - - float fpsOutput = mp.getVideoOutputFramesPerSecond(); - float fpsDecode = mp.getVideoDecodeFramesPerSecond(); - setRowValue(R.string.fps, String.format(Locale.US, "%.2f / %.2f", fpsDecode, fpsOutput)); - - long videoCachedDuration = mp.getVideoCachedDuration(); - long audioCachedDuration = mp.getAudioCachedDuration(); - long videoCachedBytes = mp.getVideoCachedBytes(); - long audioCachedBytes = mp.getAudioCachedBytes(); - long tcpSpeed = mp.getTcpSpeed(); - long bitRate = mp.getBitRate(); - long seekLoadDuration = mp.getSeekLoadDuration(); - - setRowValue(R.string.v_cache, String.format(Locale.US, "%s, %s", formatedDurationMilli(videoCachedDuration), formatedSize(videoCachedBytes))); - setRowValue(R.string.a_cache, String.format(Locale.US, "%s, %s", formatedDurationMilli(audioCachedDuration), formatedSize(audioCachedBytes))); - setRowValue(R.string.load_cost, String.format(Locale.US, "%d ms", mLoadCost)); - setRowValue(R.string.seek_cost, String.format(Locale.US, "%d ms", mSeekCost)); - setRowValue(R.string.seek_load_cost, String.format(Locale.US, "%d ms", seekLoadDuration)); - setRowValue(R.string.tcp_speed, String.format(Locale.US, "%s", formatedSpeed(tcpSpeed, 1000))); - setRowValue(R.string.bit_rate, String.format(Locale.US, "%.2f kbs", bitRate/1000f)); - - mHandler.removeMessages(MSG_UPDATE_HUD); - mHandler.sendEmptyMessageDelayed(MSG_UPDATE_HUD, 500); - } - } - } - }; -} diff --git a/OnLive/src/main/java/com/frank/living/widget/MeasureHelper.java b/OnLive/src/main/java/com/frank/living/widget/MeasureHelper.java deleted file mode 100644 index bc0fc97..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/MeasureHelper.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import android.content.Context; -import androidx.annotation.NonNull; -import android.view.View; - -import com.frank.living.R; - -import java.lang.ref.WeakReference; - -public final class MeasureHelper { - private WeakReference mWeakView; - - private int mVideoWidth; - private int mVideoHeight; - private int mVideoSarNum; - private int mVideoSarDen; - - private int mVideoRotationDegree; - - private int mMeasuredWidth; - private int mMeasuredHeight; - - private int mCurrentAspectRatio = IRenderView.AR_ASPECT_FIT_PARENT; - - public MeasureHelper(View view) { - mWeakView = new WeakReference(view); - } - - public View getView() { - if (mWeakView == null) - return null; - return mWeakView.get(); - } - - public void setVideoSize(int videoWidth, int videoHeight) { - mVideoWidth = videoWidth; - mVideoHeight = videoHeight; - } - - public void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen) { - mVideoSarNum = videoSarNum; - mVideoSarDen = videoSarDen; - } - - public void setVideoRotation(int videoRotationDegree) { - mVideoRotationDegree = videoRotationDegree; - } - - /** - * Must be called by View.onMeasure(int, int) - * - * @param widthMeasureSpec - * @param heightMeasureSpec - */ - public void doMeasure(int widthMeasureSpec, int heightMeasureSpec) { - //Log.i("@@@@", "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", " - // + MeasureSpec.toString(heightMeasureSpec) + ")"); - if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) { - int tempSpec = widthMeasureSpec; - widthMeasureSpec = heightMeasureSpec; - heightMeasureSpec = tempSpec; - } - - int width = View.getDefaultSize(mVideoWidth, widthMeasureSpec); - int height = View.getDefaultSize(mVideoHeight, heightMeasureSpec); - if (mCurrentAspectRatio == IRenderView.AR_MATCH_PARENT) { - width = widthMeasureSpec; - height = heightMeasureSpec; - } else if (mVideoWidth > 0 && mVideoHeight > 0) { - int widthSpecMode = View.MeasureSpec.getMode(widthMeasureSpec); - int widthSpecSize = View.MeasureSpec.getSize(widthMeasureSpec); - int heightSpecMode = View.MeasureSpec.getMode(heightMeasureSpec); - int heightSpecSize = View.MeasureSpec.getSize(heightMeasureSpec); - - if (widthSpecMode == View.MeasureSpec.AT_MOST && heightSpecMode == View.MeasureSpec.AT_MOST) { - float specAspectRatio = (float) widthSpecSize / (float) heightSpecSize; - float displayAspectRatio; - switch (mCurrentAspectRatio) { - case IRenderView.AR_16_9_FIT_PARENT: - displayAspectRatio = 16.0f / 9.0f; - if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) - displayAspectRatio = 1.0f / displayAspectRatio; - break; - case IRenderView.AR_4_3_FIT_PARENT: - displayAspectRatio = 4.0f / 3.0f; - if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) - displayAspectRatio = 1.0f / displayAspectRatio; - break; - case IRenderView.AR_ASPECT_FIT_PARENT: - case IRenderView.AR_ASPECT_FILL_PARENT: - case IRenderView.AR_ASPECT_WRAP_CONTENT: - default: - displayAspectRatio = (float) mVideoWidth / (float) mVideoHeight; - if (mVideoSarNum > 0 && mVideoSarDen > 0) - displayAspectRatio = displayAspectRatio * mVideoSarNum / mVideoSarDen; - break; - } - boolean shouldBeWider = displayAspectRatio > specAspectRatio; - - switch (mCurrentAspectRatio) { - case IRenderView.AR_ASPECT_FIT_PARENT: - case IRenderView.AR_16_9_FIT_PARENT: - case IRenderView.AR_4_3_FIT_PARENT: - if (shouldBeWider) { - // too wide, fix width - width = widthSpecSize; - height = (int) (width / displayAspectRatio); - } else { - // too high, fix height - height = heightSpecSize; - width = (int) (height * displayAspectRatio); - } - break; - case IRenderView.AR_ASPECT_FILL_PARENT: - if (shouldBeWider) { - // not high enough, fix height - height = heightSpecSize; - width = (int) (height * displayAspectRatio); - } else { - // not wide enough, fix width - width = widthSpecSize; - height = (int) (width / displayAspectRatio); - } - break; - case IRenderView.AR_ASPECT_WRAP_CONTENT: - default: - if (shouldBeWider) { - // too wide, fix width - width = Math.min(mVideoWidth, widthSpecSize); - height = (int) (width / displayAspectRatio); - } else { - // too high, fix height - height = Math.min(mVideoHeight, heightSpecSize); - width = (int) (height * displayAspectRatio); - } - break; - } - } else if (widthSpecMode == View.MeasureSpec.EXACTLY && heightSpecMode == View.MeasureSpec.EXACTLY) { - // the size is fixed - width = widthSpecSize; - height = heightSpecSize; - - // for compatibility, we adjust size based on aspect ratio - if (mVideoWidth * height < width * mVideoHeight) { - //Log.i("@@@", "image too wide, correcting"); - width = height * mVideoWidth / mVideoHeight; - } else if (mVideoWidth * height > width * mVideoHeight) { - //Log.i("@@@", "image too tall, correcting"); - height = width * mVideoHeight / mVideoWidth; - } - } else if (widthSpecMode == View.MeasureSpec.EXACTLY) { - // only the width is fixed, adjust the height to match aspect ratio if possible - width = widthSpecSize; - height = width * mVideoHeight / mVideoWidth; - if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) { - // couldn't match aspect ratio within the constraints - height = heightSpecSize; - } - } else if (heightSpecMode == View.MeasureSpec.EXACTLY) { - // only the height is fixed, adjust the width to match aspect ratio if possible - height = heightSpecSize; - width = height * mVideoWidth / mVideoHeight; - if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) { - // couldn't match aspect ratio within the constraints - width = widthSpecSize; - } - } else { - // neither the width nor the height are fixed, try to use actual video size - width = mVideoWidth; - height = mVideoHeight; - if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) { - // too tall, decrease both width and height - height = heightSpecSize; - width = height * mVideoWidth / mVideoHeight; - } - if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) { - // too wide, decrease both width and height - width = widthSpecSize; - height = width * mVideoHeight / mVideoWidth; - } - } - } else { - // no size yet, just adopt the given spec sizes - } - - mMeasuredWidth = width; - mMeasuredHeight = height; - } - - public int getMeasuredWidth() { - return mMeasuredWidth; - } - - public int getMeasuredHeight() { - return mMeasuredHeight; - } - - public void setAspectRatio(int aspectRatio) { - mCurrentAspectRatio = aspectRatio; - } - - @NonNull - public static String getAspectRatioText(Context context, int aspectRatio) { - String text; - switch (aspectRatio) { - case IRenderView.AR_ASPECT_FIT_PARENT: - text = context.getString(R.string.VideoView_ar_aspect_fit_parent); - break; - case IRenderView.AR_ASPECT_FILL_PARENT: - text = context.getString(R.string.VideoView_ar_aspect_fill_parent); - break; - case IRenderView.AR_ASPECT_WRAP_CONTENT: - text = context.getString(R.string.VideoView_ar_aspect_wrap_content); - break; - case IRenderView.AR_MATCH_PARENT: - text = context.getString(R.string.VideoView_ar_match_parent); - break; - case IRenderView.AR_16_9_FIT_PARENT: - text = context.getString(R.string.VideoView_ar_16_9_fit_parent); - break; - case IRenderView.AR_4_3_FIT_PARENT: - text = context.getString(R.string.VideoView_ar_4_3_fit_parent); - break; - default: - text = context.getString(R.string.N_A); - break; - } - return text; - } -} diff --git a/OnLive/src/main/java/com/frank/living/widget/MediaPlayerCompat.java b/OnLive/src/main/java/com/frank/living/widget/MediaPlayerCompat.java deleted file mode 100644 index da6f311..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/MediaPlayerCompat.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import tv.danmaku.ijk.media.player.IMediaPlayer; -import tv.danmaku.ijk.media.player.IjkMediaPlayer; -import tv.danmaku.ijk.media.player.MediaPlayerProxy; -import tv.danmaku.ijk.media.player.TextureMediaPlayer; - -public class MediaPlayerCompat { - public static String getName(IMediaPlayer mp) { - if (mp == null) { - return "null"; - } else if (mp instanceof TextureMediaPlayer) { - StringBuilder sb = new StringBuilder("TextureMediaPlayer <"); - IMediaPlayer internalMediaPlayer = ((TextureMediaPlayer) mp).getInternalMediaPlayer(); - if (internalMediaPlayer == null) { - sb.append("null>"); - } else { - sb.append(internalMediaPlayer.getClass().getSimpleName()); - sb.append(">"); - } - return sb.toString(); - } else { - return mp.getClass().getSimpleName(); - } - } - - public static IjkMediaPlayer getIjkMediaPlayer(IMediaPlayer mp) { - IjkMediaPlayer ijkMediaPlayer = null; - if (mp == null) { - return null; - } if (mp instanceof IjkMediaPlayer) { - ijkMediaPlayer = (IjkMediaPlayer) mp; - } else if (mp instanceof MediaPlayerProxy && ((MediaPlayerProxy) mp).getInternalMediaPlayer() instanceof IjkMediaPlayer) { - ijkMediaPlayer = (IjkMediaPlayer) ((MediaPlayerProxy) mp).getInternalMediaPlayer(); - } - return ijkMediaPlayer; - } - - public static void selectTrack(IMediaPlayer mp, int stream) { - IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp); - if (ijkMediaPlayer == null) - return; - ijkMediaPlayer.selectTrack(stream); - } - - public static void deselectTrack(IMediaPlayer mp, int stream) { - IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp); - if (ijkMediaPlayer == null) - return; - ijkMediaPlayer.deselectTrack(stream); - } - - public static int getSelectedTrack(IMediaPlayer mp, int trackType) { - IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp); - if (ijkMediaPlayer == null) - return -1; - return ijkMediaPlayer.getSelectedTrack(trackType); - } -} diff --git a/OnLive/src/main/java/com/frank/living/widget/SurfaceRenderView.java b/OnLive/src/main/java/com/frank/living/widget/SurfaceRenderView.java deleted file mode 100644 index c394216..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/SurfaceRenderView.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import android.annotation.TargetApi; -import android.content.Context; -import android.graphics.SurfaceTexture; -import android.os.Build; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.View; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; -import java.lang.ref.WeakReference; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import tv.danmaku.ijk.media.player.IMediaPlayer; -import tv.danmaku.ijk.media.player.ISurfaceTextureHolder; - -public class SurfaceRenderView extends SurfaceView implements IRenderView { - private MeasureHelper mMeasureHelper; - - public SurfaceRenderView(Context context) { - super(context); - initView(context); - } - - public SurfaceRenderView(Context context, AttributeSet attrs) { - super(context, attrs); - initView(context); - } - - public SurfaceRenderView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initView(context); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public SurfaceRenderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - initView(context); - } - - private void initView(Context context) { - mMeasureHelper = new MeasureHelper(this); - mSurfaceCallback = new SurfaceCallback(this); - getHolder().addCallback(mSurfaceCallback); - //noinspection deprecation - getHolder().setType(SurfaceHolder.SURFACE_TYPE_NORMAL); - } - - @Override - public View getView() { - return this; - } - - @Override - public boolean shouldWaitForResize() { - return true; - } - - //-------------------- - // Layout & Measure - //-------------------- - @Override - public void setVideoSize(int videoWidth, int videoHeight) { - if (videoWidth > 0 && videoHeight > 0) { - mMeasureHelper.setVideoSize(videoWidth, videoHeight); - getHolder().setFixedSize(videoWidth, videoHeight); - requestLayout(); - } - } - - @Override - public void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen) { - if (videoSarNum > 0 && videoSarDen > 0) { - mMeasureHelper.setVideoSampleAspectRatio(videoSarNum, videoSarDen); - requestLayout(); - } - } - - @Override - public void setVideoRotation(int degree) { - Log.e("", "SurfaceView doesn't support rotation (" + degree + ")!\n"); - } - - @Override - public void setAspectRatio(int aspectRatio) { - mMeasureHelper.setAspectRatio(aspectRatio); - requestLayout(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - mMeasureHelper.doMeasure(widthMeasureSpec, heightMeasureSpec); - setMeasuredDimension(mMeasureHelper.getMeasuredWidth(), mMeasureHelper.getMeasuredHeight()); - } - - //-------------------- - // SurfaceViewHolder - //-------------------- - - private static final class InternalSurfaceHolder implements IRenderView.ISurfaceHolder { - private SurfaceRenderView mSurfaceView; - private SurfaceHolder mSurfaceHolder; - - public InternalSurfaceHolder(@NonNull SurfaceRenderView surfaceView, - @Nullable SurfaceHolder surfaceHolder) { - mSurfaceView = surfaceView; - mSurfaceHolder = surfaceHolder; - } - - public void bindToMediaPlayer(IMediaPlayer mp) { - if (mp != null) { - if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) && - (mp instanceof ISurfaceTextureHolder)) { - ISurfaceTextureHolder textureHolder = (ISurfaceTextureHolder) mp; - textureHolder.setSurfaceTexture(null); - } - mp.setDisplay(mSurfaceHolder); - } - } - - @NonNull - @Override - public IRenderView getRenderView() { - return mSurfaceView; - } - - @Nullable - @Override - public SurfaceHolder getSurfaceHolder() { - return mSurfaceHolder; - } - - @Nullable - @Override - public SurfaceTexture getSurfaceTexture() { - return null; - } - - @Nullable - @Override - public Surface openSurface() { - if (mSurfaceHolder == null) - return null; - return mSurfaceHolder.getSurface(); - } - } - - //------------------------- - // SurfaceHolder.Callback - //------------------------- - - @Override - public void addRenderCallback(IRenderCallback callback) { - mSurfaceCallback.addRenderCallback(callback); - } - - @Override - public void removeRenderCallback(IRenderCallback callback) { - mSurfaceCallback.removeRenderCallback(callback); - } - - private SurfaceCallback mSurfaceCallback; - - private static final class SurfaceCallback implements SurfaceHolder.Callback { - private SurfaceHolder mSurfaceHolder; - private boolean mIsFormatChanged; - private int mFormat; - private int mWidth; - private int mHeight; - - private WeakReference mWeakSurfaceView; - private Map mRenderCallbackMap = new ConcurrentHashMap(); - - public SurfaceCallback(@NonNull SurfaceRenderView surfaceView) { - mWeakSurfaceView = new WeakReference(surfaceView); - } - - public void addRenderCallback(@NonNull IRenderCallback callback) { - mRenderCallbackMap.put(callback, callback); - - ISurfaceHolder surfaceHolder = null; - if (mSurfaceHolder != null) { - if (surfaceHolder == null) - surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder); - callback.onSurfaceCreated(surfaceHolder, mWidth, mHeight); - } - - if (mIsFormatChanged) { - if (surfaceHolder == null) - surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder); - callback.onSurfaceChanged(surfaceHolder, mFormat, mWidth, mHeight); - } - } - - public void removeRenderCallback(@NonNull IRenderCallback callback) { - mRenderCallbackMap.remove(callback); - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - mSurfaceHolder = holder; - mIsFormatChanged = false; - mFormat = 0; - mWidth = 0; - mHeight = 0; - - ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder); - for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) { - renderCallback.onSurfaceCreated(surfaceHolder, 0, 0); - } - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - mSurfaceHolder = null; - mIsFormatChanged = false; - mFormat = 0; - mWidth = 0; - mHeight = 0; - - ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder); - for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) { - renderCallback.onSurfaceDestroyed(surfaceHolder); - } - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, - int width, int height) { - mSurfaceHolder = holder; - mIsFormatChanged = true; - mFormat = format; - mWidth = width; - mHeight = height; - - // mMeasureHelper.setVideoSize(width, height); - - ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder); - for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) { - renderCallback.onSurfaceChanged(surfaceHolder, format, width, height); - } - } - } - - //-------------------- - // Accessibility - //-------------------- - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - super.onInitializeAccessibilityEvent(event); - event.setClassName(SurfaceRenderView.class.getName()); - } - - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - @Override - public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(info); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - info.setClassName(SurfaceRenderView.class.getName()); - } - } -} diff --git a/OnLive/src/main/java/com/frank/living/widget/TableLayoutBinder.java b/OnLive/src/main/java/com/frank/living/widget/TableLayoutBinder.java deleted file mode 100644 index ae77045..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/TableLayoutBinder.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import android.content.Context; -import androidx.appcompat.app.AlertDialog; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TableLayout; -import android.widget.TextView; - -import com.frank.living.R; - -public class TableLayoutBinder { - private Context mContext; - public ViewGroup mTableView; - public TableLayout mTableLayout; - - public TableLayoutBinder(Context context) { - this(context, R.layout.table_media_info); - } - - public TableLayoutBinder(Context context, int layoutResourceId) { - mContext = context; - mTableView = (ViewGroup) LayoutInflater.from(mContext).inflate(layoutResourceId, null); - mTableLayout = (TableLayout) mTableView.findViewById(R.id.table); - } - - public TableLayoutBinder(Context context, TableLayout tableLayout) { - mContext = context; - mTableView = tableLayout; - mTableLayout = tableLayout; - } - - public View appendRow1(String name, String value) { - return appendRow(R.layout.table_media_info_row1, name, value); - } - - public View appendRow1(int nameId, String value) { - return appendRow1(mContext.getString(nameId), value); - } - - public View appendRow2(String name, String value) { - return appendRow(R.layout.table_media_info_row2, name, value); - } - - public View appendRow2(int nameId, String value) { - return appendRow2(mContext.getString(nameId), value); - } - - public View appendSection(String name) { - return appendRow(R.layout.table_media_info_section, name, null); - } - - public View appendSection(int nameId) { - return appendSection(mContext.getString(nameId)); - } - - public View appendRow(int layoutId, String name, String value) { - ViewGroup rowView = (ViewGroup) LayoutInflater.from(mContext).inflate(layoutId, mTableLayout, false); - setNameValueText(rowView, name, value); - - mTableLayout.addView(rowView); - return rowView; - } - - public ViewHolder obtainViewHolder(View rowView) { - ViewHolder viewHolder = (ViewHolder) rowView.getTag(); - if (viewHolder == null) { - viewHolder = new ViewHolder(); - viewHolder.mNameTextView = (TextView) rowView.findViewById(R.id.name); - viewHolder.mValueTextView = (TextView) rowView.findViewById(R.id.value); - rowView.setTag(viewHolder); - } - return viewHolder; - } - - public void setNameValueText(View rowView, String name, String value) { - ViewHolder viewHolder = obtainViewHolder(rowView); - viewHolder.setName(name); - viewHolder.setValue(value); - } - - public void setValueText(View rowView, String value) { - ViewHolder viewHolder = obtainViewHolder(rowView); - viewHolder.setValue(value); - } - - public ViewGroup buildLayout() { - return mTableView; - } - - public AlertDialog.Builder buildAlertDialogBuilder() { - AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(mContext); - dlgBuilder.setView(buildLayout()); - return dlgBuilder; - } - - private static class ViewHolder { - public TextView mNameTextView; - public TextView mValueTextView; - - public void setName(String name) { - if (mNameTextView != null) { - mNameTextView.setText(name); - } - } - - public void setValue(String value) { - if (mValueTextView != null) { - mValueTextView.setText(value); - } - } - } -} diff --git a/OnLive/src/main/java/com/frank/living/widget/TextureRenderView.java b/OnLive/src/main/java/com/frank/living/widget/TextureRenderView.java deleted file mode 100644 index 472feb3..0000000 --- a/OnLive/src/main/java/com/frank/living/widget/TextureRenderView.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (C) 2015 Bilibili - * Copyright (C) 2015 Zhang Rui - * - * 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.frank.living.widget; - -import android.annotation.TargetApi; -import android.content.Context; -import android.graphics.SurfaceTexture; -import android.os.Build; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.TextureView; -import android.view.View; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; -import java.lang.ref.WeakReference; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import tv.danmaku.ijk.media.player.IMediaPlayer; -import tv.danmaku.ijk.media.player.ISurfaceTextureHolder; -import tv.danmaku.ijk.media.player.ISurfaceTextureHost; - -@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) -public class TextureRenderView extends TextureView implements IRenderView { - private static final String TAG = "TextureRenderView"; - private MeasureHelper mMeasureHelper; - - public TextureRenderView(Context context) { - super(context); - initView(context); - } - - public TextureRenderView(Context context, AttributeSet attrs) { - super(context, attrs); - initView(context); - } - - public TextureRenderView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initView(context); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public TextureRenderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - initView(context); - } - - private void initView(Context context) { - mMeasureHelper = new MeasureHelper(this); - mSurfaceCallback = new SurfaceCallback(this); - setSurfaceTextureListener(mSurfaceCallback); - } - - @Override - public View getView() { - return this; - } - - @Override - public boolean shouldWaitForResize() { - return false; - } - - @Override - protected void onDetachedFromWindow() { - mSurfaceCallback.willDetachFromWindow(); - super.onDetachedFromWindow(); - mSurfaceCallback.didDetachFromWindow(); - } - - //-------------------- - // Layout & Measure - //-------------------- - @Override - public void setVideoSize(int videoWidth, int videoHeight) { - if (videoWidth > 0 && videoHeight > 0) { - mMeasureHelper.setVideoSize(videoWidth, videoHeight); - requestLayout(); - } - } - - @Override - public void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen) { - if (videoSarNum > 0 && videoSarDen > 0) { - mMeasureHelper.setVideoSampleAspectRatio(videoSarNum, videoSarDen); - requestLayout(); - } - } - - @Override - public void setVideoRotation(int degree) { - mMeasureHelper.setVideoRotation(degree); - setRotation(degree); - } - - @Override - public void setAspectRatio(int aspectRatio) { - mMeasureHelper.setAspectRatio(aspectRatio); - requestLayout(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - mMeasureHelper.doMeasure(widthMeasureSpec, heightMeasureSpec); - setMeasuredDimension(mMeasureHelper.getMeasuredWidth(), mMeasureHelper.getMeasuredHeight()); - } - - //-------------------- - // TextureViewHolder - //-------------------- - - public IRenderView.ISurfaceHolder getSurfaceHolder() { - return new InternalSurfaceHolder(this, mSurfaceCallback.mSurfaceTexture, mSurfaceCallback); - } - - private static final class InternalSurfaceHolder implements IRenderView.ISurfaceHolder { - private TextureRenderView mTextureView; - private SurfaceTexture mSurfaceTexture; - private ISurfaceTextureHost mSurfaceTextureHost; - - public InternalSurfaceHolder(@NonNull TextureRenderView textureView, - @Nullable SurfaceTexture surfaceTexture, - @NonNull ISurfaceTextureHost surfaceTextureHost) { - mTextureView = textureView; - mSurfaceTexture = surfaceTexture; - mSurfaceTextureHost = surfaceTextureHost; - } - - @TargetApi(Build.VERSION_CODES.JELLY_BEAN) - public void bindToMediaPlayer(IMediaPlayer mp) { - if (mp == null) - return; - - if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) && - (mp instanceof ISurfaceTextureHolder)) { - ISurfaceTextureHolder textureHolder = (ISurfaceTextureHolder) mp; - mTextureView.mSurfaceCallback.setOwnSurfaceTexture(false); - - SurfaceTexture surfaceTexture = textureHolder.getSurfaceTexture(); - if (surfaceTexture != null) { - mTextureView.setSurfaceTexture(surfaceTexture); - } else { - textureHolder.setSurfaceTexture(mSurfaceTexture); - textureHolder.setSurfaceTextureHost(mTextureView.mSurfaceCallback); - } - } else { - mp.setSurface(openSurface()); - } - } - - @NonNull - @Override - public IRenderView getRenderView() { - return mTextureView; - } - - @Nullable - @Override - public SurfaceHolder getSurfaceHolder() { - return null; - } - - @Nullable - @Override - public SurfaceTexture getSurfaceTexture() { - return mSurfaceTexture; - } - - @Nullable - @Override - public Surface openSurface() { - if (mSurfaceTexture == null) - return null; - return new Surface(mSurfaceTexture); - } - } - - //------------------------- - // SurfaceHolder.Callback - //------------------------- - - @Override - public void addRenderCallback(IRenderCallback callback) { - mSurfaceCallback.addRenderCallback(callback); - } - - @Override - public void removeRenderCallback(IRenderCallback callback) { - mSurfaceCallback.removeRenderCallback(callback); - } - - private SurfaceCallback mSurfaceCallback; - - private static final class SurfaceCallback implements TextureView.SurfaceTextureListener, ISurfaceTextureHost { - private SurfaceTexture mSurfaceTexture; - private boolean mIsFormatChanged; - private int mWidth; - private int mHeight; - - private boolean mOwnSurfaceTexture = true; - private boolean mWillDetachFromWindow = false; - private boolean mDidDetachFromWindow = false; - - private WeakReference mWeakRenderView; - private Map mRenderCallbackMap = new ConcurrentHashMap(); - - public SurfaceCallback(@NonNull TextureRenderView renderView) { - mWeakRenderView = new WeakReference(renderView); - } - - public void setOwnSurfaceTexture(boolean ownSurfaceTexture) { - mOwnSurfaceTexture = ownSurfaceTexture; - } - - public void addRenderCallback(@NonNull IRenderCallback callback) { - mRenderCallbackMap.put(callback, callback); - - ISurfaceHolder surfaceHolder = null; - if (mSurfaceTexture != null) { - if (surfaceHolder == null) - surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), mSurfaceTexture, this); - callback.onSurfaceCreated(surfaceHolder, mWidth, mHeight); - } - - if (mIsFormatChanged) { - if (surfaceHolder == null) - surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), mSurfaceTexture, this); - callback.onSurfaceChanged(surfaceHolder, 0, mWidth, mHeight); - } - } - - public void removeRenderCallback(@NonNull IRenderCallback callback) { - mRenderCallbackMap.remove(callback); - } - - @Override - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { - mSurfaceTexture = surface; - mIsFormatChanged = false; - mWidth = 0; - mHeight = 0; - - ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), surface, this); - for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) { - renderCallback.onSurfaceCreated(surfaceHolder, 0, 0); - } - } - - @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { - mSurfaceTexture = surface; - mIsFormatChanged = true; - mWidth = width; - mHeight = height; - - ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), surface, this); - for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) { - renderCallback.onSurfaceChanged(surfaceHolder, 0, width, height); - } - } - - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { - mSurfaceTexture = surface; - mIsFormatChanged = false; - mWidth = 0; - mHeight = 0; - - ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), surface, this); - for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) { - renderCallback.onSurfaceDestroyed(surfaceHolder); - } - - Log.d(TAG, "onSurfaceTextureDestroyed: destroy: " + mOwnSurfaceTexture); - return mOwnSurfaceTexture; - } - - @Override - public void onSurfaceTextureUpdated(SurfaceTexture surface) { - } - - //------------------------- - // ISurfaceTextureHost - //------------------------- - - @Override - public void releaseSurfaceTexture(SurfaceTexture surfaceTexture) { - if (surfaceTexture == null) { - Log.d(TAG, "releaseSurfaceTexture: null"); - } else if (mDidDetachFromWindow) { - if (surfaceTexture != mSurfaceTexture) { - Log.d(TAG, "releaseSurfaceTexture: didDetachFromWindow(): release different SurfaceTexture"); - surfaceTexture.release(); - } else if (!mOwnSurfaceTexture) { - Log.d(TAG, "releaseSurfaceTexture: didDetachFromWindow(): release detached SurfaceTexture"); - surfaceTexture.release(); - } else { - Log.d(TAG, "releaseSurfaceTexture: didDetachFromWindow(): already released by TextureView"); - } - } else if (mWillDetachFromWindow) { - if (surfaceTexture != mSurfaceTexture) { - Log.d(TAG, "releaseSurfaceTexture: willDetachFromWindow(): release different SurfaceTexture"); - surfaceTexture.release(); - } else if (!mOwnSurfaceTexture) { - Log.d(TAG, "releaseSurfaceTexture: willDetachFromWindow(): re-attach SurfaceTexture to TextureView"); - setOwnSurfaceTexture(true); - } else { - Log.d(TAG, "releaseSurfaceTexture: willDetachFromWindow(): will released by TextureView"); - } - } else { - if (surfaceTexture != mSurfaceTexture) { - Log.d(TAG, "releaseSurfaceTexture: alive: release different SurfaceTexture"); - surfaceTexture.release(); - } else if (!mOwnSurfaceTexture) { - Log.d(TAG, "releaseSurfaceTexture: alive: re-attach SurfaceTexture to TextureView"); - setOwnSurfaceTexture(true); - } else { - Log.d(TAG, "releaseSurfaceTexture: alive: will released by TextureView"); - } - } - } - - public void willDetachFromWindow() { - Log.d(TAG, "willDetachFromWindow()"); - mWillDetachFromWindow = true; - } - - public void didDetachFromWindow() { - Log.d(TAG, "didDetachFromWindow()"); - mDidDetachFromWindow = true; - } - } - - //-------------------- - // Accessibility - //-------------------- - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - super.onInitializeAccessibilityEvent(event); - event.setClassName(TextureRenderView.class.getName()); - } - - @Override - public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(info); - info.setClassName(TextureRenderView.class.getName()); - } -} diff --git a/OnLive/src/main/project.properties b/OnLive/src/main/project.properties deleted file mode 100644 index 672cae7..0000000 --- a/OnLive/src/main/project.properties +++ /dev/null @@ -1,20 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Project target. -target=android-22 -android.library.reference.1=../../../player-arm64/src/main -android.library.reference.2=../../../player-armv5/src/main -android.library.reference.3=../../../player-armv7a/src/main -android.library.reference.4=../../../player-x86/src/main -android.library.reference.5=../../../player-java/src/main -android.library.reference.6=../../../../contrib/appcompat diff --git a/OnLive/src/main/res/drawable-xhdpi/ic_pause.png b/OnLive/src/main/res/drawable-xhdpi/ic_pause.png deleted file mode 100644 index dedce6a..0000000 Binary files a/OnLive/src/main/res/drawable-xhdpi/ic_pause.png and /dev/null differ diff --git a/OnLive/src/main/res/drawable-xhdpi/ic_play.png b/OnLive/src/main/res/drawable-xhdpi/ic_play.png deleted file mode 100644 index 72dc5a4..0000000 Binary files a/OnLive/src/main/res/drawable-xhdpi/ic_play.png and /dev/null differ diff --git a/OnLive/src/main/res/drawable-xhdpi/ic_screen_shot.png b/OnLive/src/main/res/drawable-xhdpi/ic_screen_shot.png deleted file mode 100644 index 3cb3fc3..0000000 Binary files a/OnLive/src/main/res/drawable-xhdpi/ic_screen_shot.png and /dev/null differ diff --git a/OnLive/src/main/res/drawable-xhdpi/ic_silence.png b/OnLive/src/main/res/drawable-xhdpi/ic_silence.png deleted file mode 100644 index 3ecb74f..0000000 Binary files a/OnLive/src/main/res/drawable-xhdpi/ic_silence.png and /dev/null differ diff --git a/OnLive/src/main/res/drawable-xhdpi/ic_sound.png b/OnLive/src/main/res/drawable-xhdpi/ic_sound.png deleted file mode 100644 index 8a4742a..0000000 Binary files a/OnLive/src/main/res/drawable-xhdpi/ic_sound.png and /dev/null differ diff --git a/OnLive/src/main/res/layout/activity_live.xml b/OnLive/src/main/res/layout/activity_live.xml deleted file mode 100644 index b0b9f3c..0000000 --- a/OnLive/src/main/res/layout/activity_live.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OnLive/src/main/res/layout/activity_multi_screen.xml b/OnLive/src/main/res/layout/activity_multi_screen.xml deleted file mode 100644 index 8065719..0000000 --- a/OnLive/src/main/res/layout/activity_multi_screen.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OnLive/src/main/res/layout/table_media_info.xml b/OnLive/src/main/res/layout/table_media_info.xml deleted file mode 100644 index 15b982e..0000000 --- a/OnLive/src/main/res/layout/table_media_info.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/OnLive/src/main/res/layout/table_media_info_row1.xml b/OnLive/src/main/res/layout/table_media_info_row1.xml deleted file mode 100644 index ea9ca8d..0000000 --- a/OnLive/src/main/res/layout/table_media_info_row1.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/OnLive/src/main/res/layout/table_media_info_row2.xml b/OnLive/src/main/res/layout/table_media_info_row2.xml deleted file mode 100644 index 5e2a15c..0000000 --- a/OnLive/src/main/res/layout/table_media_info_row2.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/OnLive/src/main/res/layout/table_media_info_section.xml b/OnLive/src/main/res/layout/table_media_info_section.xml deleted file mode 100644 index 971b59d..0000000 --- a/OnLive/src/main/res/layout/table_media_info_section.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/OnLive/src/main/res/mipmap-xhdpi/ic_launcher.png b/OnLive/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0..0000000 Binary files a/OnLive/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/OnLive/src/main/res/mipmap-xxhdpi/ic_launcher.png b/OnLive/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72c..0000000 Binary files a/OnLive/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/OnLive/src/main/res/values/colors.xml b/OnLive/src/main/res/values/colors.xml deleted file mode 100644 index 307526e..0000000 --- a/OnLive/src/main/res/values/colors.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - #66000000 - - @color/ijk_color_blue_500 - #E3F2FD - #BBDEFB - #90CAF9 - #64B5F6 - #42A5F5 - #2196F3 - #1E88E5 - #1976D2 - #1565C0 - #0D47A1 - - #77000000 - - diff --git a/OnLive/src/main/res/values/dimens.xml b/OnLive/src/main/res/values/dimens.xml deleted file mode 100644 index a73ffbd..0000000 --- a/OnLive/src/main/res/values/dimens.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - 16dp - 16dp - - @dimen/activity_horizontal_margin - @dimen/activity_vertical_margin - diff --git a/OnLive/src/main/res/values/ids.xml b/OnLive/src/main/res/values/ids.xml deleted file mode 100644 index 42c985e..0000000 --- a/OnLive/src/main/res/values/ids.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/OnLive/src/main/res/values/strings.xml b/OnLive/src/main/res/values/strings.xml deleted file mode 100644 index daff91a..0000000 --- a/OnLive/src/main/res/values/strings.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - OnLive - - N/A - Close - Exit - Sample - Recent - Settings - Tracks - Player - Render - Scale - Info - vdec - fps - v-cache - a-cache - load-cost - seek_cost - seek_load_cost - tcp_speed - bit_rate - - Media Information - Player - Media - Profile level - Pixel format - Resolution - Length - Stream #%d - Type - Language - Codec - Frame rate - Bit rate - Sample rate - Channels - * - * - * - - Video - Audio - Subtitle - Timed text - Meta data - Unknown - - Invalid progressive playback - Unknown - OK - - Aspect / Fit parent - Aspect / Fill parent - Aspect / Wrap content - Free / Fill parent - 16:9 / Fit parent - 4:3 / Fit parent - - Render: None - Render: SurfaceView - Render: TextureView - - Player: None - Player: AndroidMediaPlayer - Player: IjkMediaPlayer - Player: IjkExoMediaPlayer - - diff --git a/OnLive/src/main/res/values/strings_pref.xml b/OnLive/src/main/res/values/strings_pref.xml deleted file mode 100644 index 7b4978d..0000000 --- a/OnLive/src/main/res/values/strings_pref.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - General - - pref.enable_background_play - Enable background play - need Android 4.0+ - - pref.using_android_player - Using system player - - - pref.player - Choose Player - - Auto Select - AndroidMediaPlayer - IjkMediaPlayer - IjkExoMediaPlayer - - - 0 - 1 - 2 - 3 - - - Auto Select - AndroidMediaPlayer - IjkMediaPlayer - IjkExoMediaPlayer - - - - Video: ijkplayer - - pref.using_media_codec - Using MediaCodec - - - pref.using_media_codec_auto_rotate - Using MediaCodec auto rotate - - - pref.media_codec_handle_resolution_change - MediaCodec handle resolution change - - - pref.pixel_format - Pixel Format - - Auto Select - RGB 565 - RGB 888 - RGBX 8888 - YV12 - OpenGL ES2 - - - - fcc-rv16 - fcc-rv24 - fcc-rv32 - fcc-yv12 - fcc-_es2 - - - Auto Select - RGB 565 - RGB 888 - RGBX 8888 - YV12 - OpenGL ES2 - - - - Audio: ijkplayer - - pref.using_opensl_es - Using OpenSL ES - - - - RenderView - - pref.enable_no_view - Enable NoView - - - pref.enable_surface_view - Enable SurfaceView - - - pref.enable_texture_view - Enable TextureView - - - pref.enable_detached_surface_texture - Enable detached SurfaceTexture - - - - Misc - pref.using_mediadatasource - Using MediaDataSource - - - - - - diff --git a/OnLive/src/main/res/values/styles.xml b/OnLive/src/main/res/values/styles.xml deleted file mode 100644 index bb89294..0000000 --- a/OnLive/src/main/res/values/styles.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - diff --git a/OnLive/src/main/res/values/themes.xml b/OnLive/src/main/res/values/themes.xml deleted file mode 100644 index c3f1dfe..0000000 --- a/OnLive/src/main/res/values/themes.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/OnLive/src/main/res/xml/settings.xml b/OnLive/src/main/res/xml/settings.xml deleted file mode 100644 index 2b63e33..0000000 --- a/OnLive/src/main/res/xml/settings.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index b4a64a0..8663987 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,3 @@ -include ':app', ':Live', ':OnLive', ':libmp3' +include ':app' +include ':Live' +include ':libmp3'