集成完直播后提交代码
1
LiveBasic/live_pull/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
46
LiveBasic/live_pull/build.gradle
Normal file
@@ -0,0 +1,46 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion androidCompileSdkVersion
|
||||
buildToolsVersion androidBuildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion androidMinSdkVersion
|
||||
targetSdkVersion androidTargetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
consumerProguardFiles "consumer-rules.pro"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation externalAndroidDesign
|
||||
|
||||
implementation externalSimpleZXing
|
||||
|
||||
implementation externalRtsSDK
|
||||
// Add a downgraded version of the player sdk for the live project single build.
|
||||
if ("true".equalsIgnoreCase(allInOne)) {
|
||||
api externalPlayerFull
|
||||
api externalARTC
|
||||
} else {
|
||||
api externalPlayerFullDowngrade
|
||||
api externalARTCDowngrade
|
||||
}
|
||||
|
||||
implementation project(':LiveCommon:live_commonbiz')
|
||||
}
|
||||
0
LiveBasic/live_pull/consumer-rules.pro
Normal file
12
LiveBasic/live_pull/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.alivc.live.baselive_pull">
|
||||
|
||||
<application>
|
||||
<activity
|
||||
android:name=".ui.PlayerActivity"
|
||||
android:alwaysRetainTaskState="true"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AVLiveTheme" />
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.alivc.live.baselive_pull.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alivc.live.baselive_pull.R;
|
||||
import com.alivc.live.baselive_pull.bean.Constants;
|
||||
import com.alivc.live.baselive_pull.listener.ButtonClickListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PlayButtonListAdapter extends RecyclerView.Adapter {
|
||||
private ButtonClickListener clickListener;
|
||||
private boolean isItemHide = false;
|
||||
public void setClickListener(ButtonClickListener clickListener) {
|
||||
this.clickListener = clickListener;
|
||||
mButtonEnableMap = new HashMap<>();
|
||||
}
|
||||
|
||||
private List<String> mListDatas = new ArrayList<>();
|
||||
private Map<String,Boolean> mButtonEnableMap;
|
||||
public void setData(List<String> data){
|
||||
|
||||
if(data == null){
|
||||
return;
|
||||
}
|
||||
mListDatas.clear();
|
||||
mListDatas.addAll(data);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
public List<String> getData(){
|
||||
return mListDatas;
|
||||
}
|
||||
public void hideItems(boolean isItemHide){
|
||||
this.isItemHide = isItemHide;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.live_recycle_button_item_view, parent, false);
|
||||
ButtonHolder buttonHolder = new ButtonHolder(view);
|
||||
return buttonHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, @SuppressLint("RecyclerView") final int position) {
|
||||
// position 从 0开始
|
||||
ButtonHolder viewHolder= (ButtonHolder) holder;
|
||||
viewHolder.textView.setText(mListDatas.get(position));
|
||||
viewHolder.imageView.setImageResource(Constants.getLive_img_soure().get(mListDatas.get(position)));
|
||||
viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(clickListener!=null){
|
||||
clickListener.onButtonClick(mListDatas.get(position),position);
|
||||
}
|
||||
}
|
||||
});
|
||||
boolean enable = true;
|
||||
if (mButtonEnableMap.containsKey(mListDatas.get(position))){
|
||||
enable = mButtonEnableMap.get(mListDatas.get(position));
|
||||
}
|
||||
if(!enable){
|
||||
if("开始推流".equalsIgnoreCase(mListDatas.get(position))){
|
||||
viewHolder.imageView.setImageResource(R.drawable.live_push_gray);
|
||||
}
|
||||
if("数据指标".equalsIgnoreCase(mListDatas.get(position))){
|
||||
viewHolder.imageView.setImageResource(R.drawable.live_data_gray);
|
||||
}
|
||||
if("麦克风".equalsIgnoreCase(mListDatas.get(position))){
|
||||
viewHolder.imageView.setImageResource(R.drawable.live_microphone_gray);
|
||||
}
|
||||
if("调节参数".equalsIgnoreCase(mListDatas.get(position))){
|
||||
viewHolder.imageView.setImageResource(R.drawable.live_adjust_gray);
|
||||
}
|
||||
}else {
|
||||
if("开始推流".equalsIgnoreCase(mListDatas.get(position))){
|
||||
viewHolder.imageView.setImageResource(R.drawable.live_push);
|
||||
}
|
||||
if("麦克风".equalsIgnoreCase(mListDatas.get(position))){
|
||||
viewHolder.imageView.setImageResource(R.drawable.live_microphone);
|
||||
}
|
||||
if("数据指标".equalsIgnoreCase(mListDatas.get(position))){
|
||||
viewHolder.imageView.setImageResource(R.drawable.live_data);
|
||||
}
|
||||
}
|
||||
viewHolder.imageView.setEnabled(enable);
|
||||
//针对数据指标做特殊处理
|
||||
if("数据指标".equalsIgnoreCase(mListDatas.get(position))){
|
||||
viewHolder.imageView.setEnabled(true);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mListDatas.size();
|
||||
}
|
||||
|
||||
private class ButtonHolder extends RecyclerView.ViewHolder {
|
||||
private TextView textView;
|
||||
private ImageView imageView;
|
||||
public ButtonHolder(View itemView) {
|
||||
super(itemView);
|
||||
textView = itemView.findViewById(R.id.tv_anchor_text);
|
||||
imageView=itemView.findViewById(R.id.iv_anchor);
|
||||
}
|
||||
}
|
||||
|
||||
public void setButtonEnable(String buttonName,boolean enable){
|
||||
mButtonEnableMap.put(buttonName,enable);
|
||||
int position = -1;
|
||||
for (int i = 0; i < mListDatas.size(); i++) {
|
||||
if (mListDatas.get(i).equals(buttonName)){
|
||||
position = i;
|
||||
}
|
||||
}
|
||||
if (position>=0){
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.alivc.live.baselive_pull.bean;
|
||||
|
||||
import com.alivc.live.baselive_pull.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class Constants {
|
||||
private static List<String> live_push_button;
|
||||
private static List<String> live_pull_button;
|
||||
private static List<String> live_play_button;
|
||||
|
||||
private static HashMap<String,Integer> live_img_soure;
|
||||
|
||||
public static HashMap<String,Integer> getLive_img_soure() {
|
||||
return live_img_soure;
|
||||
}
|
||||
static {
|
||||
/**
|
||||
* push页面的按钮
|
||||
* */
|
||||
live_push_button = new ArrayList<>();
|
||||
live_img_soure=new HashMap<>();
|
||||
live_img_soure.put("开始推流", R.drawable.live_push);
|
||||
live_img_soure.put("美颜", R.drawable.live_beauty);
|
||||
live_img_soure.put("音效",R.drawable.live_sound);
|
||||
live_img_soure.put("摄像头",R.drawable.live_carmer);
|
||||
live_img_soure.put("静音",R.drawable.mute_btn);
|
||||
live_img_soure.put("调节参数",R.drawable.live_adjust_parm);
|
||||
live_img_soure.put("数据指标",R.drawable.live_data);
|
||||
live_push_button.add("开始推流");
|
||||
live_push_button.add("美颜");
|
||||
live_push_button.add("音效");
|
||||
live_push_button.add("静音");
|
||||
live_push_button.add("摄像头");
|
||||
live_push_button.add("调节参数");
|
||||
live_push_button.add("数据指标");
|
||||
|
||||
/**
|
||||
* pull页面按钮
|
||||
*/
|
||||
live_pull_button = new ArrayList<>();
|
||||
live_pull_button.add("暂停观看");
|
||||
live_pull_button.add("静音");
|
||||
live_pull_button.add("听筒切换");
|
||||
live_img_soure.put("暂停观看",R.drawable.finish_play);
|
||||
live_img_soure.put("听筒切换",R.drawable.telephone_change);
|
||||
|
||||
/**
|
||||
* play页面按钮
|
||||
*/
|
||||
live_play_button = new ArrayList<>();
|
||||
live_play_button.add("暂停观看");
|
||||
}
|
||||
public static List<String> getPushActivityButtonList(){
|
||||
return live_push_button;
|
||||
}
|
||||
public static List<String> getPullActivityButtonList(){
|
||||
return live_pull_button;
|
||||
}
|
||||
public static List<String> getPlayActivityButtonList(){
|
||||
return live_play_button;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.alivc.live.baselive_pull.bean.rmsbean;
|
||||
|
||||
/**
|
||||
* Auto-generated: 2024-08-06 14:42:42
|
||||
*/
|
||||
public class RMSCanvas {
|
||||
|
||||
private int w;
|
||||
private int h;
|
||||
private int bgnd;
|
||||
|
||||
public void setW(int w) {
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
public int getW() {
|
||||
return w;
|
||||
}
|
||||
|
||||
public void setH(int h) {
|
||||
this.h = h;
|
||||
}
|
||||
|
||||
public int getH() {
|
||||
return h;
|
||||
}
|
||||
|
||||
public void setBgnd(int bgnd) {
|
||||
this.bgnd = bgnd;
|
||||
}
|
||||
|
||||
public int getBgnd() {
|
||||
return bgnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Canvas{" +
|
||||
"w=" + w +
|
||||
", h=" + h +
|
||||
", bgnd=" + bgnd +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.alivc.live.baselive_pull.bean.rmsbean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Auto-generated: 2024-08-06 14:42:42
|
||||
*/
|
||||
public class RMSPeriodicBean {
|
||||
|
||||
private RMSCanvas canvas;
|
||||
private List<RMSStream> stream;
|
||||
private String source;
|
||||
private String ver;
|
||||
private long ts;
|
||||
|
||||
public void setCanvas(RMSCanvas canvas) {
|
||||
this.canvas = canvas;
|
||||
}
|
||||
|
||||
public RMSCanvas getCanvas() {
|
||||
return canvas;
|
||||
}
|
||||
|
||||
public void setStream(List<RMSStream> stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public List<RMSStream> getStream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setVer(String ver) {
|
||||
this.ver = ver;
|
||||
}
|
||||
|
||||
public String getVer() {
|
||||
return ver;
|
||||
}
|
||||
|
||||
public void setTs(long ts) {
|
||||
this.ts = ts;
|
||||
}
|
||||
|
||||
public long getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JsonRootBean{" +
|
||||
"canvas=" + canvas +
|
||||
", stream=" + stream +
|
||||
", source='" + source + '\'' +
|
||||
", ver='" + ver + '\'' +
|
||||
", ts=" + ts +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.alivc.live.baselive_pull.bean.rmsbean;
|
||||
|
||||
/**
|
||||
* Auto-generated: 2024-08-06 14:42:42
|
||||
*/
|
||||
public class RMSStream {
|
||||
|
||||
private String uid;
|
||||
private int paneid;
|
||||
private int zorder;
|
||||
private int x;
|
||||
private int y;
|
||||
private int w;
|
||||
private int h;
|
||||
private int type;
|
||||
private int status;
|
||||
private int cameraDisabled;
|
||||
private int muted;
|
||||
private int vol;
|
||||
private int vad;
|
||||
private int netQuality;
|
||||
|
||||
public void setUid(String uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setPaneid(int paneid) {
|
||||
this.paneid = paneid;
|
||||
}
|
||||
|
||||
public int getPaneid() {
|
||||
return paneid;
|
||||
}
|
||||
|
||||
public void setZorder(int zorder) {
|
||||
this.zorder = zorder;
|
||||
}
|
||||
|
||||
public int getZorder() {
|
||||
return zorder;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setW(int w) {
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
public int getW() {
|
||||
return w;
|
||||
}
|
||||
|
||||
public void setH(int h) {
|
||||
this.h = h;
|
||||
}
|
||||
|
||||
public int getH() {
|
||||
return h;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setCameraDisabled(int cameraDisabled) {
|
||||
this.cameraDisabled = cameraDisabled;
|
||||
}
|
||||
|
||||
public int getCameraDisabled() {
|
||||
return cameraDisabled;
|
||||
}
|
||||
|
||||
public void setMuted(int muted) {
|
||||
this.muted = muted;
|
||||
}
|
||||
|
||||
public int getMuted() {
|
||||
return muted;
|
||||
}
|
||||
|
||||
public void setVol(int vol) {
|
||||
this.vol = vol;
|
||||
}
|
||||
|
||||
public int getVol() {
|
||||
return vol;
|
||||
}
|
||||
|
||||
public void setVad(int vad) {
|
||||
this.vad = vad;
|
||||
}
|
||||
|
||||
public int getVad() {
|
||||
return vad;
|
||||
}
|
||||
|
||||
public void setNetQuality(int netQuality) {
|
||||
this.netQuality = netQuality;
|
||||
}
|
||||
|
||||
public int getNetQuality() {
|
||||
return netQuality;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Stream{" +
|
||||
"uid='" + uid + '\'' +
|
||||
", paneid=" + paneid +
|
||||
", zorder=" + zorder +
|
||||
", x=" + x +
|
||||
", y=" + y +
|
||||
", w=" + w +
|
||||
", h=" + h +
|
||||
", type=" + type +
|
||||
", status=" + status +
|
||||
", cameraDisabled=" + cameraDisabled +
|
||||
", muted=" + muted +
|
||||
", vol=" + vol +
|
||||
", vad=" + vad +
|
||||
", netQuality=" + netQuality +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.alivc.live.baselive_pull.listener;
|
||||
|
||||
public interface ButtonClickListener {
|
||||
void onButtonClick(String message, int position);
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
package com.alivc.live.baselive_pull.ui;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.acker.simplezxing.activity.CaptureActivity;
|
||||
import com.alivc.live.baselive_pull.R;
|
||||
import com.alivc.live.baselive_pull.bean.Constants;
|
||||
import com.alivc.live.baselive_pull.listener.ButtonClickListener;
|
||||
import com.alivc.live.baselive_pull.ui.widget.PlayButtonListView;
|
||||
import com.alivc.live.commonbiz.BuildConfig;
|
||||
import com.alivc.live.commonbiz.test.PushDemoTestConstants;
|
||||
import com.alivc.live.commonui.dialog.CommonDialog;
|
||||
import com.alivc.live.commonui.messageview.AutoScrollMessagesView;
|
||||
import com.alivc.live.commonui.utils.StatusBarUtil;
|
||||
import com.alivc.live.commonutils.TextFormatUtil;
|
||||
import com.alivc.live.commonutils.ToastUtils;
|
||||
import com.aliyun.player.AliPlayer;
|
||||
import com.aliyun.player.AliPlayerFactory;
|
||||
import com.aliyun.player.IPlayer;
|
||||
import com.aliyun.player.bean.ErrorInfo;
|
||||
import com.aliyun.player.nativeclass.PlayerConfig;
|
||||
import com.aliyun.player.source.UrlSource;
|
||||
import com.cicada.player.utils.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 直播拉流界面
|
||||
*/
|
||||
public class PlayerActivity extends AppCompatActivity implements SurfaceHolder.Callback, ButtonClickListener {
|
||||
private static final String TAG = "PlayerActivity";
|
||||
|
||||
private PlayButtonListView mButtonListView;
|
||||
private SurfaceView mSurfaceView;
|
||||
private String mPullUrl = "";
|
||||
private AliPlayer mAliPlayer;
|
||||
private EditText mPullUrlET;//拉流地址
|
||||
private Button mPullStartBtn;//开始拉流btn
|
||||
private Button mScanBtn;//扫码
|
||||
private boolean isStopPullFlag = false;//是否点击过停止播放
|
||||
private boolean isPulling = false;
|
||||
private StringBuilder mSeiStringBuilder = new StringBuilder();
|
||||
private CommonDialog mDialog;
|
||||
private AutoScrollMessagesView mSeiMessageView;
|
||||
|
||||
static {
|
||||
try {
|
||||
if (BuildConfig.MTL_BUILD_FOR_AIO) {
|
||||
System.loadLibrary("all_in_one");
|
||||
} else {
|
||||
System.loadLibrary("RtsSDK");
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
private View mPageVg;
|
||||
private ImageView mBackBtn;
|
||||
private View mInputRl;
|
||||
private TextView mTitleTv;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
StatusBarUtil.translucent(this, Color.TRANSPARENT);
|
||||
|
||||
setContentView(R.layout.activity_player);
|
||||
initPlayer();
|
||||
initView();
|
||||
|
||||
String initUrl = PushDemoTestConstants.getTestPullUrl();
|
||||
if (!initUrl.isEmpty()) {
|
||||
mPullUrlET.setText(initUrl);
|
||||
mPullUrl = initUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// 当前屏幕为横屏
|
||||
} else {
|
||||
// 当前屏幕为竖屏
|
||||
}
|
||||
}
|
||||
|
||||
private void initPlayer() {
|
||||
Logger.getInstance(this).enableConsoleLog(true);
|
||||
Logger.getInstance(this).setLogLevel(Logger.LogLevel.AF_LOG_LEVEL_TRACE);
|
||||
mAliPlayer = AliPlayerFactory.createAliPlayer(this.getApplicationContext());
|
||||
mAliPlayer.setAutoPlay(true);
|
||||
mAliPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
|
||||
@Override
|
||||
public void onRenderingStart() {
|
||||
setViewState(true);
|
||||
}
|
||||
});
|
||||
|
||||
mAliPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
|
||||
@Override
|
||||
public void onError(ErrorInfo errorInfo) {
|
||||
if (mAliPlayer != null) {
|
||||
mAliPlayer.reload();
|
||||
}
|
||||
if (mDialog == null || !mDialog.isShowing()) {
|
||||
mDialog = new CommonDialog(PlayerActivity.this);
|
||||
mDialog.setDialogTitle("Error");
|
||||
mDialog.setDialogContent(errorInfo.getMsg());
|
||||
mDialog.setConfirmButton(TextFormatUtil.getTextFormat(PlayerActivity.this, R.string.pull_cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
mDialog.setCancelButton(TextFormatUtil.getTextFormat(PlayerActivity.this, R.string.pull_restart), new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
if (mAliPlayer == null) {
|
||||
initPlayer();
|
||||
mSurfaceView = new SurfaceView(PlayerActivity.this);
|
||||
mSurfaceView.getHolder().addCallback(PlayerActivity.this);
|
||||
}
|
||||
UrlSource source = new UrlSource();
|
||||
String url = mPullUrlET.getText().toString();
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return;
|
||||
}
|
||||
source.setUri(url);
|
||||
if (mAliPlayer != null) {
|
||||
PlayerConfig cfg = mAliPlayer.getConfig();
|
||||
if (url.startsWith("artc://")) {
|
||||
cfg.mMaxDelayTime = 1000;
|
||||
cfg.mHighBufferDuration = 10;
|
||||
cfg.mStartBufferDuration = 10;
|
||||
}
|
||||
mAliPlayer.setConfig(cfg);
|
||||
mAliPlayer.setDataSource(source);
|
||||
mAliPlayer.prepare();
|
||||
}
|
||||
}
|
||||
});
|
||||
mDialog.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// TODO keria: Remove the SEI function of the player first, as it will cause bytecode conflicts between the player SDK and the push SDK.
|
||||
// mAliPlayer.setOnSeiDataListener((payload, uuid, data) -> {
|
||||
// String msg = new String(data, StandardCharsets.UTF_8);
|
||||
// String str = "[cdn]: [" + payload + "], " + msg;
|
||||
// mSeiMessageView.appendMessage(str);
|
||||
// Log.i(TAG, str);
|
||||
//
|
||||
// if (payload == 5) {
|
||||
// // implementation externalGSON
|
||||
// Gson gson = new Gson();
|
||||
// RMSPeriodicBean rmsPeriodicBean = null;
|
||||
// try {
|
||||
// // The sei message may end with \0, if we want to parse the json, we need to trim the string
|
||||
// rmsPeriodicBean = gson.fromJson(msg.trim(), RMSPeriodicBean.class);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// } finally {
|
||||
// Log.i(TAG, "rms periodic bean: " + rmsPeriodicBean);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
|
||||
mPageVg = findViewById(R.id.page_bg);
|
||||
mInputRl = findViewById(R.id.input_rl);
|
||||
mTitleTv = findViewById(R.id.title);
|
||||
mButtonListView = (PlayButtonListView) findViewById(R.id.live_buttonlistview);
|
||||
mSeiMessageView = findViewById(R.id.sei_receive_view);
|
||||
List<String> data = new ArrayList<>();
|
||||
data.addAll(Constants.getPlayActivityButtonList());
|
||||
mButtonListView.setData(data);
|
||||
mButtonListView.setClickListener(this);
|
||||
mButtonListView.setVisibility(View.GONE);
|
||||
mSurfaceView.getHolder().addCallback(this);
|
||||
mScanBtn = (Button) findViewById(R.id.player_scan_image);
|
||||
mScanBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startCaptureActivityForResult();
|
||||
}
|
||||
});
|
||||
mBackBtn = findViewById(R.id.pull_common_btn_close);
|
||||
mBackBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mPageVg.getVisibility() == View.GONE) {
|
||||
onButtonClick("暂停播放", 0);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
mPullUrlET = (EditText) findViewById(R.id.pull_common_push_url);
|
||||
mPullStartBtn = (Button) findViewById(R.id.pull_common_start_btn);
|
||||
mPullStartBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
isPulling = true;
|
||||
startPull(mPullUrlET.getText().toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
if (mAliPlayer != null) {
|
||||
mAliPlayer.setSurface(holder.getSurface());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
if (mAliPlayer != null) {
|
||||
mAliPlayer.surfaceChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
if (mAliPlayer != null) {
|
||||
mAliPlayer.setSurface(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void stopPull() {
|
||||
stopPlay();
|
||||
}
|
||||
|
||||
private void startPull(String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
ToastUtils.show(getBaseContext().getResources().getString(R.string.live_pull_addr_error));
|
||||
} else {
|
||||
ToastUtils.show("pulling...");
|
||||
startPlay();
|
||||
}
|
||||
}
|
||||
|
||||
private void startCaptureActivityForResult() {
|
||||
Intent intent = new Intent(PlayerActivity.this, CaptureActivity.class);
|
||||
startActivityForResult(intent, CaptureActivity.REQ_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case CaptureActivity.REQ_CODE:
|
||||
switch (resultCode) {
|
||||
case RESULT_OK:
|
||||
String pullUrl = data.getStringExtra(CaptureActivity.EXTRA_SCAN_RESULT);
|
||||
mPullUrlET.setText(pullUrl);
|
||||
break;
|
||||
case RESULT_CANCELED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void startPlay() {
|
||||
isPulling = true;
|
||||
mSurfaceView.setVisibility(View.VISIBLE);
|
||||
if (TextUtils.isEmpty(mPullUrl) && TextUtils.isEmpty(mPullUrlET.getText().toString())) {
|
||||
Toast.makeText(this, "拉流地址为空", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if (!TextUtils.isEmpty(mPullUrlET.getText().toString())) {
|
||||
mPullUrl = mPullUrlET.getText().toString();
|
||||
}
|
||||
UrlSource source = new UrlSource();
|
||||
String pullUrl = mPullUrlET.getText().toString();
|
||||
source.setUri(pullUrl);
|
||||
if (mAliPlayer != null) {
|
||||
PlayerConfig cfg = mAliPlayer.getConfig();
|
||||
cfg.mEnableSEI = true;
|
||||
if (pullUrl.startsWith("artc://")) {
|
||||
cfg.mMaxDelayTime = 1000;
|
||||
cfg.mHighBufferDuration = 10;
|
||||
cfg.mStartBufferDuration = 10;
|
||||
}
|
||||
mAliPlayer.setConfig(cfg);
|
||||
mAliPlayer.setDataSource(source);
|
||||
mAliPlayer.prepare();
|
||||
}
|
||||
mButtonListView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止播放
|
||||
*/
|
||||
public void stopPlay() {
|
||||
if (mAliPlayer != null) {
|
||||
mAliPlayer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (mAliPlayer != null) {
|
||||
stopPlay();
|
||||
mAliPlayer.setSurface(null);
|
||||
mAliPlayer.release();
|
||||
mAliPlayer = null;
|
||||
}
|
||||
mSeiStringBuilder.delete(0, mSeiStringBuilder.length());
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClick(String message, int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
if (isPulling) {
|
||||
stopPull();
|
||||
isPulling = false;
|
||||
setViewState(false);
|
||||
} else {
|
||||
startPull(mPullUrlET.getText().toString());
|
||||
isPulling = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setViewState(boolean isPlaying) {
|
||||
if (isPlaying) {
|
||||
mPageVg.setVisibility(View.GONE);
|
||||
mButtonListView.setVisibility(View.VISIBLE);
|
||||
mInputRl.setVisibility(View.GONE);
|
||||
mTitleTv.setTextColor(Color.WHITE);
|
||||
mBackBtn.setImageResource(R.drawable.ic_av_live_actionbar_close);
|
||||
} else {
|
||||
mPageVg.setVisibility(View.VISIBLE);
|
||||
mButtonListView.setVisibility(View.GONE);
|
||||
mInputRl.setVisibility(View.VISIBLE);
|
||||
mTitleTv.setTextColor(ContextCompat.getColor(this, R.color.border_infrared));
|
||||
mBackBtn.setImageResource(R.drawable.ic_av_live_action_bar_black_back);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.alivc.live.baselive_pull.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.alivc.live.baselive_pull.R;
|
||||
import com.alivc.live.commonutils.DensityUtil;
|
||||
|
||||
/**
|
||||
* 设置最大高度的Layout
|
||||
*/
|
||||
public class MaxHeightLayout extends LinearLayout {
|
||||
|
||||
private float mMaxRatio = 0.75f;
|
||||
private float mMaxHeight;
|
||||
private float mMinHeight;
|
||||
|
||||
public MaxHeightLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public MaxHeightLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initAtts(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public MaxHeightLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initAtts(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
private void initAtts(Context context, AttributeSet attrs){
|
||||
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.mMaxRatio);
|
||||
if (attributes != null) {
|
||||
mMaxRatio = attributes.getFloat(R.styleable.mMaxRatio_linear_max_ratio, 0.75f);
|
||||
attributes.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mMaxHeight = mMaxRatio * DensityUtil.getDisplayMetrics(getContext()).heightPixels;
|
||||
mMinHeight = DensityUtil.dip2px(getContext(), 125);
|
||||
mMaxHeight = mMaxHeight < mMinHeight ? mMinHeight : mMaxHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
if (heightMode == MeasureSpec.EXACTLY) {
|
||||
heightSize = heightSize <= mMaxHeight ? heightSize : (int) mMaxHeight;
|
||||
}
|
||||
|
||||
if (heightMode == MeasureSpec.UNSPECIFIED) {
|
||||
heightSize = heightSize <= mMaxHeight ? heightSize : (int) mMaxHeight;
|
||||
}
|
||||
|
||||
if (heightMode == MeasureSpec.AT_MOST) {
|
||||
heightSize = heightSize <= mMaxHeight ? heightSize : (int) mMaxHeight;
|
||||
}
|
||||
int maxHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode);
|
||||
super.onMeasure(widthMeasureSpec, maxHeightMeasureSpec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.alivc.live.baselive_pull.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alivc.live.baselive_pull.R;
|
||||
import com.alivc.live.baselive_pull.adapter.PlayButtonListAdapter;
|
||||
import com.alivc.live.baselive_pull.listener.ButtonClickListener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 底部按钮
|
||||
*
|
||||
* @author xlx
|
||||
*/
|
||||
public class PlayButtonListView extends FrameLayout {
|
||||
private RecyclerView mRecyclerView;
|
||||
private PlayButtonListAdapter mButtonListAdapter;
|
||||
private ButtonClickListener clickListener;
|
||||
private boolean isItemsHide = false;
|
||||
|
||||
public void setClickListener(ButtonClickListener clickListener) {
|
||||
this.clickListener = clickListener;
|
||||
}
|
||||
|
||||
|
||||
public PlayButtonListView(@NonNull Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public PlayButtonListView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public PlayButtonListView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initView(context);
|
||||
}
|
||||
|
||||
public void setData(List<String> data) {
|
||||
mButtonListAdapter.setData(data);
|
||||
}
|
||||
|
||||
public void hideItems(boolean isItemHide) {
|
||||
this.isItemsHide = isItemHide;
|
||||
mButtonListAdapter.hideItems(isItemHide);
|
||||
if (isItemHide) {
|
||||
this.setVisibility(INVISIBLE);
|
||||
} else {
|
||||
this.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isItemsHide() {
|
||||
return isItemsHide;
|
||||
}
|
||||
|
||||
private void initView(Context context) {
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.live_button_list, this, true);
|
||||
initRecyclerView(view);
|
||||
}
|
||||
|
||||
private void initRecyclerView(View view) {
|
||||
mRecyclerView = view.findViewById(R.id.live_button_recycle);
|
||||
mButtonListAdapter = new PlayButtonListAdapter();
|
||||
LinearLayoutManager manager = new LinearLayoutManager(PlayButtonListView.this.getContext());
|
||||
manager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||
mRecyclerView.setLayoutManager(manager);
|
||||
mRecyclerView.setAdapter(mButtonListAdapter);
|
||||
mRecyclerView.addItemDecoration(new SpaceItemDecortation(dip2px(getContext(), 28), getContext()));
|
||||
mRecyclerView.setItemAnimator(null);
|
||||
mRecyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
|
||||
mButtonListAdapter.setClickListener(new ButtonClickListener() {
|
||||
@Override
|
||||
public void onButtonClick(String message, int position) {
|
||||
if (clickListener != null) {
|
||||
clickListener.onButtonClick(message, position);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 将dip或dp值转换为px值,保证尺寸大小不变
|
||||
*
|
||||
* @param dipValue
|
||||
* @param dipValue DisplayMetrics类中属性density
|
||||
* @return
|
||||
*/
|
||||
private static int dip2px(Context context, float dipValue) {
|
||||
if (context == null || context.getResources() == null)
|
||||
return 1;
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dipValue * scale + 0.5f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.alivc.live.baselive_pull.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
class SpaceItemDecortation extends RecyclerView.ItemDecoration {
|
||||
private int space;//声明间距 //使用构造函数定义间距
|
||||
private Context mContext;
|
||||
|
||||
public SpaceItemDecortation(int space, Context context) {
|
||||
this.space = space;
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||
//获得当前item的位置
|
||||
int position = parent.getChildAdapterPosition(view);
|
||||
if (position == 0) {
|
||||
outRect.left = dip2px(mContext, 28);
|
||||
}
|
||||
outRect.right = this.space;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将dip或dp值转换为px值,保证尺寸大小不变
|
||||
*
|
||||
* @param dipValue
|
||||
* @param dipValue DisplayMetrics类中属性density
|
||||
* @return
|
||||
*/
|
||||
private static int dip2px(Context context, float dipValue) {
|
||||
if (context == null || context.getResources() == null)
|
||||
return 1;
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dipValue * scale + 0.5f);
|
||||
}
|
||||
}
|
||||
BIN
LiveBasic/live_pull/src/main/res/drawable-xxhdpi/colour_bg.webp
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
LiveBasic/live_pull/src/main/res/drawable-xxhdpi/finish_play.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 695 B |
|
After Width: | Height: | Size: 643 B |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
BIN
LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_beauty.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_carmer.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_data.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
BIN
LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_push.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
BIN
LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_sound.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
LiveBasic/live_pull/src/main/res/drawable-xxhdpi/mute_btn.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="20dp"/>
|
||||
<stroke android:color="#4DCFE1"
|
||||
android:width="1px"/>
|
||||
<solid android:color="#4DCFE1"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="20dp"/>
|
||||
<stroke android:color="@color/color_background_black_alpha_30"
|
||||
android:width="1px"/>
|
||||
<solid android:color="@color/color_background_black_alpha_30"/>
|
||||
</shape>
|
||||
118
LiveBasic/live_pull/src/main/res/layout/activity_player.xml
Normal file
@@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/surface_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/page_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/colour_bg" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/pull_common_btn_close"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="44dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="33dp"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_av_live_action_bar_black_back" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="44dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="33dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/pull_rtc_enter_name_tv"
|
||||
android:textColor="#23262F"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginTop="77dp"
|
||||
android:background="#23262F" />
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/input_rl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_size_36"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="107dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:background="@drawable/shape_bg_search">
|
||||
|
||||
<Button
|
||||
android:id="@+id/player_scan_image"
|
||||
android:layout_width="19dp"
|
||||
android:layout_height="19dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/view_margin_18"
|
||||
android:background="@drawable/ic_live_scan" />
|
||||
|
||||
<View
|
||||
android:id="@+id/pull_common_slipt_line"
|
||||
android:layout_width="1px"
|
||||
android:layout_height="19dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_toRightOf="@id/player_scan_image"
|
||||
android:background="#40ffffff" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/pull_common_push_url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_margin_22"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="80dp"
|
||||
android:layout_toRightOf="@id/pull_common_slipt_line"
|
||||
android:background="@null"
|
||||
android:hint="@string/view_string_hint_pull_url"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/wheel_white"
|
||||
android:textColorHint="@color/wheel_white"
|
||||
android:textSize="@dimen/view_size_text_17" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/pull_common_start_btn"
|
||||
android:layout_width="@dimen/view_width_size_64"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentRight="true"
|
||||
android:background="@drawable/shape_bg_btn_green"
|
||||
android:text="@string/live_pull"
|
||||
android:textColor="@color/color_title_text_black"
|
||||
android:textSize="@dimen/view_size_text_17" />
|
||||
</RelativeLayout>
|
||||
|
||||
<com.alivc.live.baselive_pull.ui.widget.PlayButtonListView
|
||||
android:id="@+id/live_buttonlistview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_marginBottom="36dp" />
|
||||
|
||||
<com.alivc.live.commonui.messageview.AutoScrollMessagesView
|
||||
android:id="@+id/sei_receive_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="180dp"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_marginBottom="100dp"
|
||||
android:padding="10dp" />
|
||||
|
||||
</FrameLayout>
|
||||
158
LiveBasic/live_pull/src/main/res/layout/common_dialog.xml
Normal file
@@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:background="#80000000">
|
||||
|
||||
<com.alivc.live.baselive_pull.ui.widget.MaxHeightLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="50dp"
|
||||
android:layout_marginRight="50dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/live_dialog_bg"
|
||||
android:minHeight="125dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="20dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginLeft="30dp"
|
||||
android:layout_marginRight="30dp"
|
||||
android:includeFontPadding="false"
|
||||
android:singleLine="true"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="18sp"
|
||||
android:visibility="gone"
|
||||
tools:text="18dp大标题"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/dialog_content_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="30dp"
|
||||
android:layout_marginTop="9dp"
|
||||
android:layout_marginRight="30dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/dialog_content_container2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/dialog_content_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="none">
|
||||
|
||||
<!-- 解决内部滑动问题 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_tip_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:includeFontPadding="false"
|
||||
android:lineSpacingExtra="3dp"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="14sp"
|
||||
tools:text="14dp提示内容" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/dialog_expand_content_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/dialog_btn_top_line"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:background="#3A3D48"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_cancel_btn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:singleLine="true"
|
||||
android:text="取消"
|
||||
android:textColor="#4DCFE1"
|
||||
android:textSize="18sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<View
|
||||
android:id="@+id/dialog_btn_line"
|
||||
android:layout_width="0.5dp"
|
||||
android:layout_height="52dp"
|
||||
android:background="#3A3D48"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_confirm_btn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:singleLine="true"
|
||||
android:text="确定"
|
||||
android:textColor="#4DCFE1"
|
||||
android:textSize="18sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 解决弹窗中心点与屏幕高度45%的位置重合 -->
|
||||
<View
|
||||
android:id="@+id/dialog_bottom_space"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp" />
|
||||
</com.alivc.live.baselive_pull.ui.widget.MaxHeightLayout>
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/live_button_recycle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<ImageView
|
||||
android:id="@+id/iv_anchor"
|
||||
android:layout_width="44dp"
|
||||
android:layout_height="44dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/live_carmer"/>
|
||||
<TextView
|
||||
android:id="@+id/tv_anchor_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:textColor="@color/color_text_white"
|
||||
android:textSize="10sp"
|
||||
android:layout_gravity="center"
|
||||
android:text="1212"
|
||||
android:gravity="center"
|
||||
/>
|
||||
</LinearLayout>
|
||||
6
LiveBasic/live_pull/src/main/res/values-en/strings.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="pull_rtc_enter_name_tv">Live Streaming</string>
|
||||
<string name="view_string_hint_pull_url">Enter the source URL.</string>
|
||||
<string name="pull_restart">Retry</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="pull_rtc_enter_name_tv">拉流播放</string>
|
||||
<string name="pull_rtc_enter_name_desc">支持常见协议,如FLV、RTMP、HLS、RTS等</string>
|
||||
<string name="view_string_hint_pull_url">请输入拉流url</string>
|
||||
<string name="pull_restart">重试</string>
|
||||
<string name="live_pull">拉流</string>
|
||||
<string name="live_pull_addr_error">拉流地址错误,请检查后重新输入</string>
|
||||
</resources>
|
||||
10
LiveBasic/live_pull/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="pull_rtc_enter_name_tv">Live Streaming</string>
|
||||
<string name="pull_rtc_enter_name_desc">Common protocols are supported, such as FLV, RTMP, HLS, and RTS.</string>
|
||||
<string name="view_string_hint_pull_url">Enter the source URL.</string>
|
||||
<string name="pull_restart">Retry</string>
|
||||
<string name="live_pull">Pull</string>
|
||||
<string name="live_pull_addr_error"> Pull address error, please check and re-enter </string>
|
||||
|
||||
</resources>
|
||||