优化播放控制

This commit is contained in:
sifacai@outlook.com 2022-08-24 00:02:29 +08:00
parent df3e210841
commit ecb1c29d17
9 changed files with 280 additions and 65 deletions

3
.idea/misc.xml generated
View File

@ -3,7 +3,10 @@
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/code/VlcJellyfin/app/src/main/res/drawable/popmenu_focus.xml" value="0.1555" />
<entry key="..\:/code/VlcJellyfin/app/src/main/res/layout/activity_vlc_player.xml" value="0.286231884057971" />
<entry key="..\:/code/VlcJellyfin/app/src/main/res/layout/popmenu.xml" value="0.14479166666666668" />
<entry key="..\:/code/VlcJellyfin/app/src/main/res/layout/popmenu_item.xml" value="0.14479166666666668" />
<entry key="..\:/work/VlcJellyfin/app/src/main/res/drawable/shape_user_focus.xml" value="0.1625" />
<entry key="..\:/work/VlcJellyfin/app/src/main/res/drawable/shape_user_focus_VH.xml" value="0.1625" />
<entry key="..\:/work/VlcJellyfin/app/src/main/res/drawable/shape_user_focus_vholder.xml" value="0.1625" />

View File

@ -0,0 +1,91 @@
package org.sifacai.vlcjellyfin;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import java.util.ArrayList;
public class PopMenu extends PopupWindow {
public class menu{
public int groupid;
public int id;
public int orderid;
public String name;
public View v;
}
private Context context;
private ArrayList<menu> items;
private View attView;
private LinearLayout contentView;
public PopMenu(Context context, View attView) {
super(context);
this.context = context;
items = new ArrayList<>();
setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
setOutsideTouchable(true);
setFocusable(true);
setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
contentView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.popmenu,null);
setContentView(contentView);
this.attView = attView;
}
public menu add(int groupid,int id,int orderid,String name){
menu m = new menu();
m.groupid = groupid;
m.id = id;
m.orderid = orderid;
m.name = name;
View v = LayoutInflater.from(context).inflate(R.layout.popmenu_item,null);
m.v = v;
((TextView)v).setText(name);
items.add(m);
contentView.addView(v);
return m;
}
public void show(){
contentView.measure(makeDropDownMeasureSpec(getWidth())
,makeDropDownMeasureSpec(getHeight()));
int offx = 0;
int offy = contentView.getMeasuredHeight() + attView.getHeight();
showAsDropDown(attView,offx,-offy);
}
public void show(int index){
show();
items.get(index).v.requestFocus();
}
public void show(String name){
show();
for (menu m:items) {
if(m.name.equals(name)){
m.v.requestFocus();
}
}
}
@SuppressWarnings("ResourceType")
private static int makeDropDownMeasureSpec(int measureSpec) {
int mode;
if (measureSpec == ViewGroup.LayoutParams.WRAP_CONTENT) {
mode = View.MeasureSpec.UNSPECIFIED;
} else {
mode = View.MeasureSpec.EXACTLY;
}
return View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.getSize(measureSpec), mode);
}
}

View File

@ -3,16 +3,14 @@ package org.sifacai.vlcjellyfin;
import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import okhttp3.Headers;
import okhttp3.MediaType;
@ -145,6 +143,29 @@ public class Utils {
okhttpSend(url,json);
}
/**
* 根据缩放类型取名称
* @param scaleName
* @return
*/
public static String getVlcScaleTypeName(String scaleName){
switch (scaleName){
case "SURFACE_BEST_FIT":
return "自动";
case "SURFACE_FIT_SCREEN":
return "适应屏幕";
case "SURFACE_FILL":
return "满屏";
case "SURFACE_16_9":
return "16:9";
case "SURFACE_4_3":
return "4:3";
case "SURFACE_ORIGINAL":
return "原始";
}
return "";
}
public static int dp2px(Context context, float value) {
return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, context.getResources().getDisplayMetrics()) + 0.5f);
}

View File

@ -22,12 +22,13 @@ import java.util.Timer;
import java.util.TimerTask;
public class VlcPlayerActivity extends BaseActivity implements MediaPlayer.EventListener
, View.OnClickListener
, PopupMenu.OnMenuItemClickListener{
, View.OnClickListener {
private static final String TAG = "VLC播放器";
public final int TrackType_Subtitle = 0;
public final int TrackType_Audio = 1;
public final int TrackType_Playlist = 2;
public final int Type_SubtitleTrack = 0;
public final int Type_AudioTrack = 1;
public final int Type_Playlist = 2;
public final int Type_Scale = 3;
public final int Type_Speed = 4;
private Activity mActivity;
private MediaPlayer mediaPlayer;
@ -42,6 +43,8 @@ public class VlcPlayerActivity extends BaseActivity implements MediaPlayer.Event
private TextView videoTitle;
private TextView currTime;
private TextView countTime;
private TextView speedBtn;
private TextView scaleBtn;
private ImageView preBtn;
private ImageView nextBtn;
private ImageView playPauseBtn;
@ -54,9 +57,11 @@ public class VlcPlayerActivity extends BaseActivity implements MediaPlayer.Event
private Timer progressTime = null;
private PopupMenu playListMenu = null; //播放列表
private PopupMenu subTrackMenu = null; //字幕菜单
private PopupMenu audioTrackMenu = null; //单轨菜单
private PopMenu playListMenu = null; //播放列表
private PopMenu subTrackMenu = null; //字幕菜单
private PopMenu audioTrackMenu = null; //单轨菜单
private PopMenu scaleTypeMenu = null; //缩放菜单
private PopMenu speedMenu = null; //播放速率菜单
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -104,7 +109,7 @@ public class VlcPlayerActivity extends BaseActivity implements MediaPlayer.Event
showLoadingDialog();
}
setLoadingText("加载进度:%" + Buffering);
if(Buffering >= 100){
if (Buffering >= 100) {
Log.d(TAG, "onEvent: 取消loading");
dismissLoadingDialog();
}
@ -160,6 +165,8 @@ public class VlcPlayerActivity extends BaseActivity implements MediaPlayer.Event
videoTitle = findViewById(R.id.videoTitle); // 标题
currTime = findViewById(R.id.currTime);
countTime = findViewById(R.id.countTime);
speedBtn = findViewById(R.id.speedBtn);
scaleBtn = findViewById(R.id.scaleBtn);
preBtn = findViewById(R.id.preBtn);
nextBtn = findViewById(R.id.nextBtn);
playPauseBtn = findViewById(R.id.playPauseBtn);
@ -176,9 +183,9 @@ public class VlcPlayerActivity extends BaseActivity implements MediaPlayer.Event
public boolean onKey(View view, int i, KeyEvent keyEvent) {
boolean rv = false;
int keycode = keyEvent.getKeyCode();
if(keycode == KeyEvent.KEYCODE_DPAD_RIGHT){
if (keycode == KeyEvent.KEYCODE_DPAD_RIGHT) {
rv = setTimeOnSeekBar(mediaPlayer.getTime() + (long) (mediaPlayer.getLength() * 0.05));
}else if(keycode == KeyEvent.KEYCODE_DPAD_LEFT){
} else if (keycode == KeyEvent.KEYCODE_DPAD_LEFT) {
rv = setTimeOnSeekBar(mediaPlayer.getTime() - (long) (mediaPlayer.getLength() * 0.05));
}
return rv;
@ -189,61 +196,110 @@ public class VlcPlayerActivity extends BaseActivity implements MediaPlayer.Event
/**
* 初始化字幕和单轨菜单
*/
private void initMenu(){
private void initMenu() {
MediaPlayer.TrackDescription[] subTrackList = mediaPlayer.getSpuTracks();
MediaPlayer.TrackDescription[] audioTrackList = mediaPlayer.getAudioTracks();
playListBtn = findViewById(R.id.playListBtn);
subTracksBtn = findViewById(R.id.subTracksBtn);
audioTracksBtn = findViewById(R.id.audioTracksBtn);
if(Utils.playList.size() > 1){
if (Utils.playList.size() > 1) {
initPlayListMenu();
}else{
} else {
playListBtn.setVisibility(View.GONE);
}
if(null != subTrackList && subTrackList.length > 1){
if (null != subTrackList && subTrackList.length > 1) {
initSubTrackMenu(subTrackList);
}else{
} else {
subTracksBtn.setVisibility(View.GONE);
}
if(null != audioTrackList && audioTrackList.length > 1) {
if (null != audioTrackList && audioTrackList.length > 1) {
initAudioTrackMenu(audioTrackList);
}else{
} else {
audioTracksBtn.setVisibility(View.GONE);
}
//初始化缩放键
scaleBtn.setOnClickListener(this);
scaleBtn.setText(Utils.getVlcScaleTypeName(mediaPlayer.getVideoScale().name()));
scaleTypeMenu = new PopMenu(this,scaleBtn);
MediaPlayer.ScaleType[] scaleTypes = MediaPlayer.ScaleType.values();
for(int i=0;i<scaleTypes.length;i++){
PopMenu.menu menu = scaleTypeMenu.add(Type_Scale,i,i,Utils.getVlcScaleTypeName(scaleTypes[i].name()));
final int Si = i;
menu.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
scaleTypeMenu.dismiss();
if(mediaPlayer.getVideoScale() != scaleTypes[Si]){
mediaPlayer.setVideoScale(scaleTypes[Si]);
scaleBtn.setText(Utils.getVlcScaleTypeName(mediaPlayer.getVideoScale().name()));
}
}
});
}
//初始化速率键
speedBtn.setOnClickListener(this);
speedMenu = new PopMenu(this,speedBtn);
}
private void initPlayListMenu(){
playListMenu = new PopupMenu(this,playListBtn);
for(int i=0;i<Utils.playList.size();i++){
playListMenu.getMenu().add(TrackType_Playlist,i,i,Utils.playList.get(i).Name);
private void initPlayListMenu() {
playListMenu = new PopMenu(this, playListBtn); //new PopupMenu(this,playListBtn);
for (int i = 0; i < Utils.playList.size(); i++) {
PopMenu.menu m = playListMenu.add(Type_Playlist, i, i, Utils.playList.get(i).Name);
m.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
playListMenu.dismiss();
if (m.id != Utils.playIndex) {
Utils.playIndex = m.id;
play();
}
}
});
}
playListMenu.setOnMenuItemClickListener(this);
subTracksBtn.setOnClickListener(this);
playListBtn.setOnClickListener(this);
}
/**
* 初始化字幕菜单
*
* @param subTrackList
*/
private void initSubTrackMenu(MediaPlayer.TrackDescription[] subTrackList){
subTrackMenu = new PopupMenu(this,subTracksBtn);
for(int i=0;i<subTrackList.length;i++){
subTrackMenu.getMenu().add(0,i,i,subTrackList[i].name);
private void initSubTrackMenu(MediaPlayer.TrackDescription[] subTrackList) {
subTrackMenu = new PopMenu(this, subTracksBtn);
for (int i = 0; i < subTrackList.length; i++) {
PopMenu.menu m = subTrackMenu.add(Type_SubtitleTrack,i,i,subTrackList[i].name);
m.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
subTrackMenu.dismiss();
if(m.id != mediaPlayer.getSpuTrack()){
mediaPlayer.setSpuTrack(m.id);
}
}
});
}
subTrackMenu.setOnMenuItemClickListener(this);
subTracksBtn.setOnClickListener(this);
}
private void initAudioTrackMenu(MediaPlayer.TrackDescription[] audioTrackList){
audioTrackMenu = new PopupMenu(this,audioTracksBtn);
for(int i=0;i<audioTrackList.length;i++){
audioTrackMenu.getMenu().add(TrackType_Audio,i,i,audioTrackList[i].name);
private void initAudioTrackMenu(MediaPlayer.TrackDescription[] audioTrackList) {
audioTrackMenu = new PopMenu(this, audioTracksBtn);
for (int i = 0; i < audioTrackList.length; i++) {
PopMenu.menu m = audioTrackMenu.add(Type_SubtitleTrack,i,i,audioTrackList[i].name);
m.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
audioTrackMenu.dismiss();
if(m.id != mediaPlayer.getAudioTrack()){
mediaPlayer.setAudioTrack(m.id);
}
}
});
}
audioTrackMenu.setOnMenuItemClickListener(this);
audioTracksBtn.setOnClickListener(this);
}
@ -374,7 +430,7 @@ public class VlcPlayerActivity extends BaseActivity implements MediaPlayer.Event
/**
* 设置播放器位置
*/
public boolean setTimeOnSeekBar(Long p){
public boolean setTimeOnSeekBar(Long p) {
if (p < mediaPlayer.getLength() && p > 0) {
mediaPlayer.setTime(p);
setSeekBar(p);
@ -445,33 +501,14 @@ public class VlcPlayerActivity extends BaseActivity implements MediaPlayer.Event
playOrpause();
} else if (id == R.id.stopBtn) {
stop();
} else if (id == R.id.subTracksBtn){
subTrackMenu.show();
subTrackMenu.getMenu().getItem(mediaPlayer.getSpuTrack()).setChecked(true);
} else if (id == R.id.audioTracksBtn){
audioTrackMenu.show();
audioTrackMenu.getMenu().getItem(mediaPlayer.getAudioTrack()).setChecked(true);
} else if (id == R.id.playListBtn){
playListMenu.show();
playListMenu.getMenu().getItem(Utils.playIndex).setChecked(true);
} else if (id == R.id.subTracksBtn) {
subTrackMenu.show(mediaPlayer.getSpuTrack());
} else if (id == R.id.audioTracksBtn) {
audioTrackMenu.show(mediaPlayer.getAudioTrack());
} else if (id == R.id.playListBtn) {
playListMenu.show(Utils.playIndex);
} else if (id == R.id.scaleBtn){
scaleTypeMenu.show(Utils.getVlcScaleTypeName(mediaPlayer.getVideoScale().name()));
}
}
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
int groupid = menuItem.getGroupId();
int itemid = menuItem.getItemId();
if(groupid == TrackType_Subtitle){
mediaPlayer.setSpuTrack(itemid);
return true;
}else if(groupid == TrackType_Audio){
mediaPlayer.setAudioTrack(itemid);
return true;
}else if(groupid == TrackType_Playlist){
Utils.playIndex = itemid;
play();
}
return false;
}
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true">
<shape>
<corners android:radius="0dp" />
<stroke android:width="0dp" android:color="@color/color_FFFFFF" />
<solid android:color="@color/color_6C3D3D3D" />
</shape>
</item>
<item android:state_focused="false">
<shape>
<corners android:radius="0dp" />
<solid android:color="@color/color_66000000"/>
</shape>
</item>
</selector>

View File

@ -131,6 +131,28 @@
android:src="@drawable/ic_outline_skip_next_48"
android:focusable="true"/>
<TextView
android:id="@+id/speedBtn"
android:layout_width="@dimen/button_width"
android:layout_height="@dimen/button_height"
android:layout_marginLeft="@dimen/button_margin_left"
android:background="@drawable/shape_user_focus"
android:textSize="@dimen/title_size"
android:focusable="true" />
<TextView
android:id="@+id/scaleBtn"
android:layout_width="wrap_content"
android:minWidth="@dimen/button_width"
android:layout_height="@dimen/button_height"
android:layout_marginLeft="@dimen/button_margin_left"
android:background="@drawable/shape_user_focus"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:gravity="center"
android:textSize="@dimen/title_size"
android:focusable="true" />
<ImageView
android:id="@+id/subTracksBtn"
android:layout_width="@dimen/button_width"

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="0dp"
android:layout_margin="0dp" >
</LinearLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="100dp"
android:maxWidth="300dp"
android:padding="10dp"
android:layout_margin="0dp"
android:textColor="@color/white"
android:textSize="20dp"
android:background="@drawable/popmenu_focus"
android:focusable="true" >
</TextView>

View File

@ -4,4 +4,7 @@
<item name="android:background">@null</item>
<item name="android:windowBackground">@drawable/app_bg</item>
</style>
<style name="popmenuStyle" parent="@android:style/Widget.PopupMenu">
<item name="android:popupBackground">@color/color_6CFFFFFF</item><!-- popMenu的背景色-->
</style>
</resources>