Skip to content

Commit

Permalink
EXO播放器版本更新
Browse files Browse the repository at this point in the history
nextlib 版本更新
添加多abi版本编译
设置页面打开的选择弹框每次打开后直接展示到对应的item上
设置-页面优化
添加额外的视频设置
修改生成的名称方便多版本生成
  • Loading branch information
Klosw committed Jun 15, 2024
1 parent ab3aca4 commit cd7e5e1
Show file tree
Hide file tree
Showing 21 changed files with 2,278 additions and 164 deletions.
39 changes: 30 additions & 9 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ def static buildTime() {
}

android {
compileSdk 33
compileSdk 34

defaultConfig {
applicationId 'com.github.tvbox.osc.tk'
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0.".concat(buildTime())
Expand All @@ -32,10 +32,30 @@ android {
release {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
minifyEnabled true

}
}
flavorDimensions += "abi"
productFlavors {
armeabi {
dimension = "abi"
ndk {
abiFilters 'armeabi-v7a'
}
}
arm64 {
dimension = "abi"
ndk {
abiFilters 'arm64-v8a'
}
}
}
applicationVariants.configureEach { variant ->
variant.outputs.configureEach { output ->
// 构建自定义文件名
def fileName = "TVBox_${variant.buildType.name}-${variant.flavorName}.apk"
outputFileName = fileName
}
}

compileOptions {
Expand Down Expand Up @@ -103,13 +123,14 @@ dependencies {
implementation 'com.orhanobut:hawk:2.0.1'
implementation 'net.sourceforge.streamsupport:android-retrofuture:1.7.4'
implementation 'androidx.annotation:annotation:1.6.0'
implementation "androidx.media3:media3-exoplayer:1.1.1"
implementation "androidx.media3:media3-ui:1.1.1"
implementation "androidx.media3:media3-exoplayer-dash:1.1.1"
implementation "androidx.media3:media3-exoplayer-hls:1.1.1"
implementation "androidx.media3:media3-exoplayer-rtsp:1.1.1"
implementation "androidx.media3:media3-datasource-rtmp:1.1.1"
implementation 'androidx.media3:media3-common:1.1.1'
implementation "androidx.media3:media3-exoplayer:1.3.1"
implementation "androidx.media3:media3-ui:1.3.1"
implementation "androidx.media3:media3-exoplayer-dash:1.3.1"
implementation "androidx.media3:media3-exoplayer-hls:1.3.1"
implementation "androidx.media3:media3-exoplayer-rtsp:1.3.1"
implementation "androidx.media3:media3-datasource-rtmp:1.3.1"
implementation 'androidx.media3:media3-common:1.3.1'
implementation "com.github.anilbeesetti.nextlib:nextlib-media3ext:0.7.1"



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import android.app.Activity;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.app.RemoteAction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
Expand Down Expand Up @@ -81,6 +80,7 @@
import com.github.tvbox.osc.util.DefaultConfig;
import com.github.tvbox.osc.util.FileUtils;
import com.github.tvbox.osc.util.HawkConfig;
import com.github.tvbox.osc.util.HawkUtils;
import com.github.tvbox.osc.util.LOG;
import com.github.tvbox.osc.util.M3U8;
import com.github.tvbox.osc.util.MD5;
Expand Down Expand Up @@ -564,7 +564,7 @@ public boolean areContentsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonN
void openMyVideo() {
Intent i = new Intent();
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setAction(android.content.Intent.ACTION_VIEW);
i.setAction(Intent.ACTION_VIEW);
if (videoURL == null) return;
i.setDataAndType(Uri.parse(videoURL), "video/*");
startActivity(Intent.createChooser(i, "Open Video with ..."));
Expand Down Expand Up @@ -651,7 +651,7 @@ void playUrl(String url, HashMap<String, String> headers) {
.headers(hheaders)
.execute(new AbsCallback<String>() {
@Override
public void onSuccess(com.lzy.okgo.model.Response<String> response) {
public void onSuccess(Response<String> response) {
String content = response.body();
if (!content.startsWith("#EXTM3U")) {
startPlayUrl(url, headers);
Expand Down Expand Up @@ -704,7 +704,7 @@ public void onSuccess(com.lzy.okgo.model.Response<String> response) {
.headers(hheaders)
.execute(new AbsCallback<String>() {
@Override
public void onSuccess(com.lzy.okgo.model.Response<String> response) {
public void onSuccess(Response<String> response) {
String content = response.body();
int ilast = finalforwardurl.lastIndexOf('/');
RemoteServer.m3u8Content = M3U8.purify(finalforwardurl.substring(0, ilast + 1), content);
Expand All @@ -723,7 +723,7 @@ public String convertResponse(okhttp3.Response response) throws Throwable {
}

@Override
public void onError(com.lzy.okgo.model.Response<String> response) {
public void onError(Response<String> response) {
super.onError(response);
startPlayUrl(url, headers);
}
Expand All @@ -736,7 +736,7 @@ public String convertResponse(okhttp3.Response response) throws Throwable {
}

@Override
public void onError(com.lzy.okgo.model.Response<String> response) {
public void onError(Response<String> response) {
super.onError(response);
startPlayUrl(url, headers);
}
Expand Down Expand Up @@ -1001,8 +1001,22 @@ void initPlayerCfg() {
}
try {
if (!mVodPlayerCfg.has("pl")) {
mVodPlayerCfg.put("pl", (sourceBean.getPlayerType() == -1) ? (int) Hawk.get(HawkConfig.PLAY_TYPE, 1) : sourceBean.getPlayerType());
int playType = Hawk.get(HawkConfig.PLAY_TYPE, 1);
boolean configurationFile = HawkUtils.getVodPlayerPreferredConfigurationFile();
int playerType = sourceBean.getPlayerType();
if (configurationFile && playerType != -1) {
playType = playerType;
}
mVodPlayerCfg.put("pl", playType);
} else {
//如果手动修改过那么该处的默认值不生效
// boolean configurationFile = HawkUtils.getVodPlayerPreferredConfigurationFile();
// if (!configurationFile) {
// int playType = Hawk.get(HawkConfig.PLAY_TYPE, 0);
// mVodPlayerCfg.put("pl", playType);
// }
}

if (!mVodPlayerCfg.has("pr")) {
mVodPlayerCfg.put("pr", Hawk.get(HawkConfig.PLAY_RENDER, 0));
}
Expand Down Expand Up @@ -1074,14 +1088,18 @@ public void onUserLeaveHint() {
} else {
ratio = new Rational(16, 9);
}
List<RemoteAction> actions = new ArrayList<>();
actions.add(generateRemoteAction(android.R.drawable.ic_media_previous, BROADCAST_ACTION_PREV, "Prev", "Play Previous"));
actions.add(generateRemoteAction(android.R.drawable.ic_media_play, BROADCAST_ACTION_PLAYPAUSE, "Play/Pause", "Play or Pause"));
actions.add(generateRemoteAction(android.R.drawable.ic_media_next, BROADCAST_ACTION_NEXT, "Next", "Play Next"));

List<android.app.RemoteAction> actions = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
actions.add(generateRemoteAction(android.R.drawable.ic_media_previous, BROADCAST_ACTION_PREV, "Prev", "Play Previous"));
actions.add(generateRemoteAction(android.R.drawable.ic_media_play, BROADCAST_ACTION_PLAYPAUSE, "Play/Pause", "Play or Pause"));
actions.add(generateRemoteAction(android.R.drawable.ic_media_next, BROADCAST_ACTION_NEXT, "Next", "Play Next"));
}
PictureInPictureParams params = new PictureInPictureParams.Builder()
.setAspectRatio(ratio)
.setActions(actions).build();
enterPictureInPictureMode(params);

mController.hideBottom();
mVideoView.postDelayed(() -> {
if (!mVideoView.isPlaying()) {
Expand Down Expand Up @@ -1138,16 +1156,14 @@ protected void onPause() {
}

@RequiresApi(api = Build.VERSION_CODES.O)
private RemoteAction generateRemoteAction(int iconResId, int actionCode, String title, String desc) {

final PendingIntent intent =
PendingIntent.getBroadcast(
private android.app.RemoteAction generateRemoteAction(int iconResId, int actionCode, String title, String desc) {
final PendingIntent intent = PendingIntent.getBroadcast(
PlayActivity.this,
actionCode,
new Intent(BROADCAST_ACTION).putExtra("action", actionCode),
0);
final Icon icon = Icon.createWithResource(PlayActivity.this, iconResId);
return (new RemoteAction(icon, title, desc, intent));
return (new android.app.RemoteAction(icon, title, desc, intent));
}

// takagen99 : PIP fix to close video when close window
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package com.github.tvbox.osc.ui.dialog;

import android.content.Context;
import android.util.Log;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.blankj.utilcode.util.LogUtils;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.github.tvbox.osc.BuildConfig;
import com.github.tvbox.osc.R;
import com.github.tvbox.osc.util.HawkUtils;
import com.github.tvbox.osc.widget.OnItemClickListener;
import com.github.tvbox.osc.widget.OnItemSelectedListener;
import com.owen.tvrecyclerview.widget.TvRecyclerView;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

public class MediaSettingDialog extends BaseDialog {

public MediaSettingDialog(@NonNull @NotNull Context context) {
super(context);
setContentView(R.layout.dialog_media_setting);
setCanceledOnTouchOutside(true);
TvRecyclerView listMediaTitle = findViewById(R.id.list_media_title);
TvRecyclerView listMediaContent = findViewById(R.id.list_media_content);
//右侧设置内容数据
MediaSettingContentAdapter contentAdapter = new MediaSettingContentAdapter();
listMediaContent.setAdapter(contentAdapter);
//默认填充第一个
List<MediaSettingEntity> listTitle = getListTitle();
contentAdapter.replaceData(getListContent(listTitle.get(0).tag));
//左侧数据展示
MediaSettingTitleAdapter titleAdapter = new MediaSettingTitleAdapter(listTitle);
listMediaTitle.setAdapter(titleAdapter);
listMediaTitle.setOnItemListener((OnItemSelectedListener) (tvRecyclerView, view, i) -> {
//重新替换右侧数据
contentAdapter.replaceData(getListContent(titleAdapter.getItem(i).tag));
listMediaContent.setSelectedPosition(0);
});

listMediaContent.setOnItemListener((OnItemClickListener) (tvRecyclerView, view, i) -> {
//处理点击事件
MediaSettingEntity item = contentAdapter.getItem(i);
MediaSettingEnum mediaSettingEnum = MediaSettingEnum.valueOf(item.tag);
switch (mediaSettingEnum) {
case IjkMediaCodecMode:
HawkUtils.nextIJKCodec();
break;
case IjkCache:
HawkUtils.nextIJKCache();
break;
case ExoRenderer:
HawkUtils.nextExoRenderer();
break;
case ExoRendererMode:
HawkUtils.nextExoRendererMode();
break;
case VodPlayerPreferred:
HawkUtils.nextVodPlayerPreferred();
break;
}
contentAdapter.refreshNotifyItemChanged(i);
});
}

public List<MediaSettingEntity> getListTitle() {
List<MediaSettingEntity> contentEntityList = new ArrayList<>();
String[] stringTitle = getContext().getResources().getStringArray(R.array.media_title);
String[] tags = getContext().getResources().getStringArray(R.array.media_title_tag);
for (int i = 0; i < stringTitle.length; i++) {
String content = stringTitle[i];
String tag = tags[i];
contentEntityList.add(new MediaSettingEntity(content, tag));
}
return contentEntityList;
}


/**
* 获取 展示用的数据以及tag
*
* @param key
*/
public List<MediaSettingEntity> getListContent(String key) {
List<MediaSettingEntity> contentEntityList = new ArrayList<>();
try {
int id = getContext().getResources().getIdentifier("media_content_" + key, "array", BuildConfig.APPLICATION_ID);
String[] strings = getContext().getResources().getStringArray(id);
int idTag = getContext().getResources().getIdentifier("media_content_tag_" + key, "array", BuildConfig.APPLICATION_ID);
String[] tags = getContext().getResources().getStringArray(idTag);
for (int i = 0; i < strings.length; i++) {
String content = strings[i];
String tag = tags[i];
contentEntityList.add(new MediaSettingEntity(content, tag));
}
} catch (Exception e) {
LogUtils.w(Log.getStackTraceString(e));
}
return contentEntityList;
}

//左侧数据展示
public static class MediaSettingTitleAdapter extends BaseQuickAdapter<MediaSettingEntity, BaseViewHolder> {
public MediaSettingTitleAdapter(List<MediaSettingEntity> strings) {
super(R.layout.item_dialog_select, strings);
}

@Override
protected void convert(BaseViewHolder helper, MediaSettingEntity item) {
TextView name = helper.getView(R.id.tvName);
name.setText(item.content);
}
}

//右侧的数据展示
public static class MediaSettingContentAdapter extends BaseQuickAdapter<MediaSettingEntity, BaseViewHolder> {
public MediaSettingContentAdapter() {
super(R.layout.item_dialog_select2);
}

@Override
protected void convert(@NonNull BaseViewHolder helper, MediaSettingEntity item) {
TextView tvTitle = helper.getView(R.id.tv_title);
tvTitle.setText(item.content);
TextView tvContent = helper.getView(R.id.tv_content);
MediaSettingEnum mediaSettingEnum = MediaSettingEnum.valueOf(item.tag);
switch (mediaSettingEnum) {
case IjkMediaCodecMode:
tvContent.setText(HawkUtils.getIJKCodec());
break;
case IjkCache:
tvContent.setText(HawkUtils.getIJKCacheDesc());
break;
case ExoRenderer:
tvContent.setText(HawkUtils.getExoRendererDesc());
break;
case ExoRendererMode:
tvContent.setText(HawkUtils.getExoRendererModeDesc());
break;
case VodPlayerPreferred:
tvContent.setText(HawkUtils.getVodPlayerPreferredDesc());
break;
}
}
}

//数据Bean
public static class MediaSettingEntity {
//展示名称
private String content;
//处理方式
private String tag;
//描述作用
private String describe;

public MediaSettingEntity(String content) {
this.content = content;
}

public MediaSettingEntity(String content, String tag) {
this.content = content;
this.tag = tag;
}

public MediaSettingEntity(String content, String tag, String describe) {
this.content = content;
this.tag = tag;
this.describe = describe;
}
}

//数据枚举
public enum MediaSettingEnum {
IjkMediaCodecMode, IjkCache, ExoRenderer, ExoRendererMode,VodPlayerPreferred
}
}
Loading

0 comments on commit cd7e5e1

Please sign in to comment.