集成完直播后提交代码
19
LiveBasic/live_push/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.alivc.live.baselive_push">
|
||||
|
||||
<application>
|
||||
<activity
|
||||
android:name=".ui.PushConfigActivity"
|
||||
android:alwaysRetainTaskState="true"
|
||||
android:configChanges="uiMode"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppThemePlayer" />
|
||||
<activity
|
||||
android:name=".ui.LivePushActivity"
|
||||
android:alwaysRetainTaskState="true"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|screenLayout|uiMode"
|
||||
android:exported="false"
|
||||
android:theme="@style/AppThemePlayer" />
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.alivc.live.baselive_push.adapter;
|
||||
|
||||
import android.view.SurfaceView;
|
||||
|
||||
import com.alivc.live.baselive_push.ui.LivePushActivity;
|
||||
import com.alivc.live.pusher.AlivcLivePusher;
|
||||
|
||||
public interface IPushController {
|
||||
public AlivcLivePusher getLivePusher();
|
||||
public LivePushActivity.PauseState getPauseStateListener();
|
||||
public SurfaceView getPreviewView();
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.alivc.live.baselive_push.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
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.commonui.bean.MusicInfo;
|
||||
import com.alivc.live.baselive_push.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MusicSelectAdapter extends RecyclerView.Adapter<MusicSelectAdapter.MusicViewHolder> {
|
||||
|
||||
private static final String BGM_ASSETS_PATH = "alivc_resource/BGM/";
|
||||
private static final String NETWORK_BGM_URL = "http://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/51991/cn_zh/1511776743437/JUST%202017.mp3";
|
||||
|
||||
private final ArrayList<MusicInfo> sBGMList = new ArrayList<>();
|
||||
|
||||
private OnItemClick mOnItemClick = null;
|
||||
|
||||
private int mPosition = 0;
|
||||
|
||||
public MusicSelectAdapter(Context context) {
|
||||
MusicInfo info = new MusicInfo(context.getResources().getString(R.string.no_music), "", "", "");
|
||||
sBGMList.add(info);
|
||||
ArrayList<MusicInfo> list = getMusicInfoResources(context);
|
||||
sBGMList.addAll(list);
|
||||
MusicInfo info1 = new MusicInfo(context.getResources().getString(R.string.internet_music), "", "", NETWORK_BGM_URL);
|
||||
sBGMList.add(info1);
|
||||
}
|
||||
|
||||
private static ArrayList<MusicInfo> getMusicInfoResources(Context context) {
|
||||
ArrayList<MusicInfo> musicInfos = new ArrayList<>();
|
||||
String bgmDirectoryPath = context.getFilesDir() + File.separator + BGM_ASSETS_PATH;
|
||||
File bgmDirectory = new File(bgmDirectoryPath);
|
||||
if (bgmDirectory.isDirectory()) {
|
||||
File[] bgmFiles = bgmDirectory.listFiles((dir, name) -> name.endsWith(".mp3"));
|
||||
if (bgmFiles != null) {
|
||||
for (File file : bgmFiles) {
|
||||
MusicInfo musicInfo = new MusicInfo();
|
||||
musicInfo.setMusicName(file.getName());
|
||||
musicInfo.setPath(file.getAbsolutePath());
|
||||
|
||||
musicInfos.add(musicInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return musicInfos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.music_select_item_info, parent, false);
|
||||
MusicViewHolder holder = new MusicViewHolder(itemView);
|
||||
holder.tvMusicName = (TextView) itemView.findViewById(R.id.music_name);
|
||||
holder.tvMusicCheck = (ImageView) itemView.findViewById(R.id.music_check);
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
if (mOnItemClick != null) {
|
||||
mOnItemClick.onItemClick(sBGMList.get(holder.getAdapterPosition()), holder.getAdapterPosition());
|
||||
}
|
||||
int lastPosition = mPosition;
|
||||
mPosition = holder.getAdapterPosition();
|
||||
notifyItemChanged(lastPosition);
|
||||
notifyItemChanged(mPosition);
|
||||
|
||||
}
|
||||
});
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final MusicViewHolder holder, final int position) {
|
||||
MusicInfo musicInfo = sBGMList.get(position);
|
||||
|
||||
if (mPosition == position) {
|
||||
holder.tvMusicCheck.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.tvMusicCheck.setVisibility(View.GONE);
|
||||
}
|
||||
if (musicInfo != null) {
|
||||
holder.tvMusicName.setText(musicInfo.getMusicName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return sBGMList.size();
|
||||
}
|
||||
|
||||
static class MusicViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tvMusicName;
|
||||
ImageView tvMusicCheck;
|
||||
|
||||
public MusicViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnItemClick(OnItemClick onItemClick) {
|
||||
mOnItemClick = onItemClick;
|
||||
}
|
||||
|
||||
public interface OnItemClick {
|
||||
void onItemClick(MusicInfo musicInfo, int position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.alivc.live.baselive_push.adapter;
|
||||
|
||||
public interface OnSoundEffectChangedListener {
|
||||
void onSoundEffectChangeVoiceModeSelected(int position);
|
||||
|
||||
void onSoundEffectRevertBSelected(int position);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.alivc.live.baselive_push.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alivc.live.baselive_push.R;
|
||||
import com.alivc.live.baselive_push.bean.SoundEffectBean;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SoundEffectRecyclerViewAdapter extends RecyclerView.Adapter<SoundEffectRecyclerViewAdapter.SoundEffectViewHolder> {
|
||||
|
||||
private final Map<Integer, SoundEffectBean> mDataMap;
|
||||
private int mSelectIndex = 0;
|
||||
private OnSoundEffectItemClickListener mOnSoundEffectItemClickListener;
|
||||
private final int mNormalColor;
|
||||
private final int mSelectColor;
|
||||
|
||||
public SoundEffectRecyclerViewAdapter(Context context, Map<Integer, SoundEffectBean> data) {
|
||||
this.mDataMap = data;
|
||||
mNormalColor = context.getResources().getColor(R.color.camera_panel_content);
|
||||
mSelectColor = context.getResources().getColor(R.color.colorBaseStyle);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@NotNull
|
||||
@Override
|
||||
public SoundEffectViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
|
||||
View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_sound_effect_recycler_view, parent, false);
|
||||
return new SoundEffectViewHolder(inflate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull @NotNull SoundEffectViewHolder holder, int position) {
|
||||
SoundEffectBean soundEffectBean = mDataMap.get(position);
|
||||
if (soundEffectBean != null) {
|
||||
holder.mSoundEffectTitle.setText(soundEffectBean.getDescriptionId());
|
||||
holder.mIconImageView.setImageResource(soundEffectBean.getIconId());
|
||||
if (mSelectIndex == position) {
|
||||
holder.mIconImageView.setColorFilter(mSelectColor);
|
||||
holder.mSoundEffectTitle.setTextColor(mSelectColor);
|
||||
} else {
|
||||
holder.mIconImageView.setColorFilter(mNormalColor);
|
||||
holder.mSoundEffectTitle.setTextColor(mNormalColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mDataMap == null ? 0 : mDataMap.keySet().size();
|
||||
}
|
||||
|
||||
public void setSelectIndex(int index) {
|
||||
this.mSelectIndex = index;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public class SoundEffectViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private final TextView mSoundEffectTitle;
|
||||
private final ImageView mIconImageView;
|
||||
|
||||
public SoundEffectViewHolder(@NonNull @NotNull View itemView) {
|
||||
super(itemView);
|
||||
ConstraintLayout mRootView = itemView.findViewById(R.id.item_root);
|
||||
mSoundEffectTitle = itemView.findViewById(R.id.item_sound_effect_title);
|
||||
mIconImageView = itemView.findViewById(R.id.iv_icon);
|
||||
|
||||
mRootView.setOnClickListener(view -> {
|
||||
if (mOnSoundEffectItemClickListener != null && mSelectIndex != getAdapterPosition()) {
|
||||
mOnSoundEffectItemClickListener.onSoundEffectItemClick(getAdapterPosition());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnSoundEffectItemClickListener {
|
||||
void onSoundEffectItemClick(int position);
|
||||
}
|
||||
|
||||
public void setOnSoundEffectItemClickListener(OnSoundEffectItemClickListener listener) {
|
||||
this.mOnSoundEffectItemClickListener = listener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.alivc.live.baselive_push.bean;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* json解析工具类 其实对于数组解析有一些问题
|
||||
* @author
|
||||
*/
|
||||
public class GsonUtils {
|
||||
|
||||
public static Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* 返回List对象
|
||||
* @param str
|
||||
* @param type new TypeToken<ArrayList<T>>(){}.getType()
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getListFromJSON(String str, Type type) {
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
return gson.fromJson(str, type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回List对象
|
||||
* @param str
|
||||
* @param cls
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> getListFromJSON(String str, Class<T> cls)
|
||||
{
|
||||
Type type = new TypeToken<ArrayList<JsonObject>>()
|
||||
{}.getType();
|
||||
ArrayList<JsonObject> jsonObjects = gson.fromJson(str, type);
|
||||
ArrayList<T> arrayList = new ArrayList<>();
|
||||
for (JsonObject jsonObject : jsonObjects)
|
||||
{
|
||||
arrayList.add(gson.fromJson(jsonObject, cls));
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回对象
|
||||
* @param str
|
||||
* @param cls
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getObjFromJSON(String str, Class<T> cls) {
|
||||
// try {
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
return gson.fromJson(str, cls);
|
||||
}
|
||||
return null;
|
||||
// }catch (Exception e) {
|
||||
// return null;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回JsonString
|
||||
* @return
|
||||
*/
|
||||
public static String beanToJSONString(Object bean) {
|
||||
return new Gson().toJson(bean);
|
||||
}
|
||||
|
||||
|
||||
public static String JSONTokener(String in) {
|
||||
// consume an optional byte order mark (BOM) if it exists
|
||||
if (in != null && in.startsWith("\ufeff")) {
|
||||
in = in.substring(1);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.alivc.live.baselive_push.bean;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import com.alivc.live.baselive_push.R;
|
||||
import com.alivc.live.pusher.AlivcLivePushAudioEffectReverbMode;
|
||||
import com.alivc.live.pusher.AlivcLivePushAudioEffectVoiceChangeMode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class SoundEffectBean implements Serializable {
|
||||
|
||||
//icon drawable resId
|
||||
private int iconId;
|
||||
//description string resId
|
||||
private int descriptionId;
|
||||
private String name;
|
||||
|
||||
|
||||
public SoundEffectBean() {
|
||||
}
|
||||
|
||||
public SoundEffectBean(@StringRes int descriptionId, String name) {
|
||||
this.descriptionId = descriptionId;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
public SoundEffectBean(@DrawableRes int iconId, @StringRes int descriptionId, String name) {
|
||||
this.iconId = iconId;
|
||||
this.descriptionId = descriptionId;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
public void setIconId(@IdRes int iconId) {
|
||||
this.iconId = iconId;
|
||||
}
|
||||
|
||||
public int getDescriptionId() {
|
||||
return descriptionId;
|
||||
}
|
||||
|
||||
public void setDescriptionId(@StringRes int descriptionId) {
|
||||
this.descriptionId = descriptionId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 音效
|
||||
*/
|
||||
public static class SoundEffectChangeVoiceBean {
|
||||
private static final HashMap<Integer, SoundEffectBean> mLivePushSoundEffectChangeVoice = new HashMap<>();
|
||||
|
||||
static {
|
||||
mLivePushSoundEffectChangeVoice.put(0, new SoundEffectBean(R.drawable.ic_live_push_sound_effect_off, R.string.sound_effect_changevoice_off, AlivcLivePushAudioEffectVoiceChangeMode.SOUND_EFFECT_OFF.name()));
|
||||
mLivePushSoundEffectChangeVoice.put(1, new SoundEffectBean(R.drawable.ic_live_push_sound_effect_oldman, R.string.sound_effect_changevoice_oldman, AlivcLivePushAudioEffectVoiceChangeMode.SOUND_EFFECT_OLD_MAN.name()));
|
||||
mLivePushSoundEffectChangeVoice.put(2, new SoundEffectBean(R.drawable.ic_live_push_sound_effect_babyboy, R.string.sound_effect_changevoice_babyboy, AlivcLivePushAudioEffectVoiceChangeMode.SOUND_EFFECT_BABY_BOY.name()));
|
||||
mLivePushSoundEffectChangeVoice.put(3, new SoundEffectBean(R.drawable.ic_live_push_sound_effect_babygirl, R.string.sound_effect_changevoice_babygirl, AlivcLivePushAudioEffectVoiceChangeMode.SOUND_EFFECT_BABY_GIRL.name()));
|
||||
mLivePushSoundEffectChangeVoice.put(4, new SoundEffectBean(R.drawable.ic_live_push_sound_effect_robot, R.string.sound_effect_changevoice_robot, AlivcLivePushAudioEffectVoiceChangeMode.SOUND_EFFECT_ROBOT.name()));
|
||||
mLivePushSoundEffectChangeVoice.put(5, new SoundEffectBean(R.drawable.ic_live_push_sound_effect_daimo, R.string.sound_effect_changevoice_daimo, AlivcLivePushAudioEffectVoiceChangeMode.SOUND_EFFECT_DEMON.name()));
|
||||
mLivePushSoundEffectChangeVoice.put(6, new SoundEffectBean(R.drawable.ic_live_push_sound_effect_ktv, R.string.sound_effect_changevoice_ktv, AlivcLivePushAudioEffectVoiceChangeMode.SOUND_EFFECT_KTV.name()));
|
||||
mLivePushSoundEffectChangeVoice.put(7, new SoundEffectBean(R.drawable.ic_live_push_sound_effect_echo, R.string.sound_effect_changevoice_echo, AlivcLivePushAudioEffectVoiceChangeMode.SOUND_EFFECT_ECHO.name()));
|
||||
}
|
||||
|
||||
public static HashMap<Integer, SoundEffectBean> getLivePushSoundEffectChangeVoice() {
|
||||
return mLivePushSoundEffectChangeVoice;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 混响
|
||||
*/
|
||||
public static class SoundEffectReverb {
|
||||
private static final HashMap<Integer, SoundEffectBean> mLivePushSoundEffectReverb = new HashMap<>();
|
||||
|
||||
static {
|
||||
mLivePushSoundEffectReverb.put(0, new SoundEffectBean(R.string.sound_effect_reverb_off, AlivcLivePushAudioEffectReverbMode.REVERB_OFF.name()));
|
||||
mLivePushSoundEffectReverb.put(1, new SoundEffectBean(R.string.sound_effect_reverb_vocal1, AlivcLivePushAudioEffectReverbMode.REVERB_VOCAL_I.name()));
|
||||
mLivePushSoundEffectReverb.put(2, new SoundEffectBean(R.string.sound_effect_reverb_vocal2, AlivcLivePushAudioEffectReverbMode.REVERB_VOCAL_II.name()));
|
||||
mLivePushSoundEffectReverb.put(3, new SoundEffectBean(R.string.sound_effect_reverb_bathroom, AlivcLivePushAudioEffectReverbMode.REVERB_BATHROOM.name()));
|
||||
mLivePushSoundEffectReverb.put(4, new SoundEffectBean(R.string.sound_effect_reverb_smallroom_bright, AlivcLivePushAudioEffectReverbMode.REVERB_SMALL_ROOM_BRIGHT.name()));
|
||||
mLivePushSoundEffectReverb.put(5, new SoundEffectBean(R.string.sound_effect_reverb_smallroom_dark, AlivcLivePushAudioEffectReverbMode.REVERB_SMALL_ROOM_DARK.name()));
|
||||
mLivePushSoundEffectReverb.put(6, new SoundEffectBean(R.string.sound_effect_reverb_mediumroom, AlivcLivePushAudioEffectReverbMode.REVERB_MEDIUM_ROOM.name()));
|
||||
mLivePushSoundEffectReverb.put(7, new SoundEffectBean(R.string.sound_effect_reverb_largeroom, AlivcLivePushAudioEffectReverbMode.REVERB_LARGE_ROOM.name()));
|
||||
mLivePushSoundEffectReverb.put(8, new SoundEffectBean(R.string.sound_effect_reverb_churchhall, AlivcLivePushAudioEffectReverbMode.REVERB_CHURCH_HALL.name()));
|
||||
}
|
||||
|
||||
public static HashMap<Integer, SoundEffectBean> getLivePushSoundEffectReverb() {
|
||||
return mLivePushSoundEffectReverb;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
package com.alivc.live.baselive_push.ui;
|
||||
|
||||
import static com.alivc.live.pusher.AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_LEFT;
|
||||
import static com.alivc.live.pusher.AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_RIGHT;
|
||||
import static com.alivc.live.pusher.AlivcPreviewOrientationEnum.ORIENTATION_PORTRAIT;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.Camera;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Bundle;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.alivc.live.annotations.AlivcLiveMode;
|
||||
import com.alivc.live.baselive_push.R;
|
||||
import com.alivc.live.baselive_push.adapter.IPushController;
|
||||
import com.alivc.live.commonutils.NetWorkUtils;
|
||||
import com.alivc.live.commonui.utils.StatusBarUtil;
|
||||
import com.alivc.live.pusher.AlivcLivePushConfig;
|
||||
import com.alivc.live.pusher.AlivcLivePushStatsInfo;
|
||||
import com.alivc.live.pusher.AlivcLivePusher;
|
||||
import com.alivc.live.pusher.AlivcPreviewOrientationEnum;
|
||||
import com.alivc.live.pusher.SurfaceStatus;
|
||||
import com.alivc.live.pusher.WaterMarkInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LivePushActivity extends AppCompatActivity implements IPushController {
|
||||
private static final String TAG = "LivePushActivity";
|
||||
private static final int FLING_MIN_DISTANCE = 50;
|
||||
private static final int FLING_MIN_VELOCITY = 0;
|
||||
private final long REFRESH_INTERVAL = 1000;
|
||||
private static final String URL_KEY = "url_key";
|
||||
private static final String ASYNC_KEY = "async_key";
|
||||
private static final String AUDIO_ONLY_KEY = "audio_only_key";
|
||||
private static final String VIDEO_ONLY_KEY = "video_only_key";
|
||||
private static final String ORIENTATION_KEY = "orientation_key";
|
||||
private static final String CAMERA_ID = "camera_id";
|
||||
private static final String FLASH_ON = "flash_on";
|
||||
private static final String AUTH_TIME = "auth_time";
|
||||
private static final String PRIVACY_KEY = "privacy_key";
|
||||
private static final String MIX_EXTERN = "mix_extern";
|
||||
private static final String MIX_MAIN = "mix_main";
|
||||
private static final String BEAUTY_CHECKED = "beauty_checked";
|
||||
private static final String FPS = "fps";
|
||||
private static final String WATER_MARK_INFOS = "water_mark";
|
||||
public static final int REQ_CODE_PUSH = 0x1112;
|
||||
public static final int CAPTURE_PERMISSION_REQUEST_CODE = 0x1123;
|
||||
|
||||
// 互动模式下的预览view
|
||||
private FrameLayout mPreviewContainer;
|
||||
// 普通模式(默认)下的预览view
|
||||
private SurfaceView mPreviewView;
|
||||
private ViewPager mViewPager;
|
||||
|
||||
private List<Fragment> mFragmentList = new ArrayList<>();
|
||||
private FragmentAdapter mFragmentAdapter;
|
||||
|
||||
private GestureDetector mDetector;
|
||||
private ScaleGestureDetector mScaleDetector;
|
||||
private LivePushFragment mLivePushFragment;
|
||||
private AlivcLivePushConfig mAlivcLivePushConfig;
|
||||
|
||||
private static AlivcLivePusher mAlivcLivePusher = null;
|
||||
private String mPushUrl = null;
|
||||
|
||||
private boolean mAsync = false;
|
||||
private boolean mAudioOnly = false;
|
||||
private boolean mVideoOnly = false;
|
||||
private int mOrientation = ORIENTATION_PORTRAIT.ordinal();
|
||||
|
||||
private SurfaceStatus mSurfaceStatus = SurfaceStatus.UNINITED;
|
||||
// private Handler mHandler = new Handler();
|
||||
private boolean isPause = false;
|
||||
|
||||
private int mCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
|
||||
private boolean mFlash = false;
|
||||
private boolean mMixExtern = false;
|
||||
private boolean mMixMain = false;
|
||||
private boolean mBeautyOn = true;
|
||||
AlivcLivePushStatsInfo alivcLivePushStatsInfo = null;
|
||||
private String mAuthTime = "";
|
||||
private String mPrivacyKey = "";
|
||||
|
||||
// private ConnectivityChangedReceiver mChangedReceiver = new ConnectivityChangedReceiver();
|
||||
|
||||
private static int mNetWork = 0;
|
||||
private int mFps;
|
||||
|
||||
private LivePushViewModel mLivePushViewModel;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
StatusBarUtil.translucent(this, Color.TRANSPARENT);
|
||||
|
||||
mLivePushViewModel = new ViewModelProvider(this).get(LivePushViewModel.class);
|
||||
|
||||
mPushUrl = getIntent().getStringExtra(URL_KEY);
|
||||
|
||||
mAsync = getIntent().getBooleanExtra(ASYNC_KEY, false);
|
||||
mAudioOnly = getIntent().getBooleanExtra(AUDIO_ONLY_KEY, false);
|
||||
mVideoOnly = getIntent().getBooleanExtra(VIDEO_ONLY_KEY, false);
|
||||
mOrientation = getIntent().getIntExtra(ORIENTATION_KEY, ORIENTATION_PORTRAIT.ordinal());
|
||||
mCameraId = getIntent().getIntExtra(CAMERA_ID, Camera.CameraInfo.CAMERA_FACING_FRONT);
|
||||
mFlash = getIntent().getBooleanExtra(FLASH_ON, false);
|
||||
mAuthTime = getIntent().getStringExtra(AUTH_TIME);
|
||||
mPrivacyKey = getIntent().getStringExtra(PRIVACY_KEY);
|
||||
mMixExtern = getIntent().getBooleanExtra(MIX_EXTERN, false);
|
||||
mMixMain = getIntent().getBooleanExtra(MIX_MAIN, false);
|
||||
mBeautyOn = getIntent().getBooleanExtra(BEAUTY_CHECKED, true);
|
||||
mFps = getIntent().getIntExtra(FPS, 0);
|
||||
mAlivcLivePushConfig = (AlivcLivePushConfig) getIntent().getSerializableExtra(AlivcLivePushConfig.CONFIG);
|
||||
ArrayList<WaterMarkInfo> waterMarkInfos = (ArrayList<WaterMarkInfo>) getIntent().getSerializableExtra(WATER_MARK_INFOS);
|
||||
|
||||
mLivePushViewModel.initReadFile(mAlivcLivePushConfig);
|
||||
|
||||
setOrientation(mOrientation);
|
||||
setContentView(R.layout.activity_push);
|
||||
initView();
|
||||
|
||||
if (mAlivcLivePushConfig.getLivePushMode() == AlivcLiveMode.AlivcLiveInteractiveMode) {
|
||||
// 同一进程下,只能设置一次;如需修改,需要杀进程再设置
|
||||
mAlivcLivePushConfig.setH5CompatibleMode(true);
|
||||
}
|
||||
mAlivcLivePusher = new AlivcLivePusher();
|
||||
try {
|
||||
mAlivcLivePusher.init(getApplicationContext(), mAlivcLivePushConfig);
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
showDialog(this, e.getMessage());
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
showDialog(this, e.getMessage());
|
||||
}
|
||||
|
||||
if (mAlivcLivePushConfig.getLivePushMode() == AlivcLiveMode.AlivcLiveInteractiveMode) {
|
||||
mAlivcLivePusher.startPreview(this, mPreviewContainer, true);
|
||||
}
|
||||
|
||||
mLivePushFragment = LivePushFragment.newInstance(mAlivcLivePushConfig, mPushUrl, mAsync, mAudioOnly, mVideoOnly, mCameraId, mFlash, mAlivcLivePushConfig.getQualityMode().getQualityMode(),
|
||||
mAuthTime, mPrivacyKey, mMixExtern, mMixMain, mBeautyOn, mFps, mOrientation, waterMarkInfos);
|
||||
initViewPager();
|
||||
mScaleDetector = new ScaleGestureDetector(getApplicationContext(), mScaleGestureDetector);
|
||||
mDetector = new GestureDetector(getApplicationContext(), mGestureDetector);
|
||||
mNetWork = NetWorkUtils.getAPNType(this);
|
||||
}
|
||||
|
||||
public void initView() {
|
||||
if (mAlivcLivePushConfig.getLivePushMode() == AlivcLiveMode.AlivcLiveInteractiveMode) {
|
||||
//互动模式需要 FrameLayout
|
||||
mPreviewContainer = findViewById(R.id.preview_container);
|
||||
mPreviewContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mPreviewView = (SurfaceView) findViewById(R.id.preview_view);
|
||||
mPreviewView.getHolder().addCallback(mCallback);
|
||||
mPreviewView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void initViewPager() {
|
||||
mViewPager = (ViewPager) findViewById(R.id.tv_pager);
|
||||
mFragmentList.add(mLivePushFragment);
|
||||
mFragmentAdapter = new FragmentAdapter(this.getSupportFragmentManager(), mFragmentList);
|
||||
mViewPager.setAdapter(mFragmentAdapter);
|
||||
mViewPager.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
if (motionEvent.getPointerCount() >= 2 && mScaleDetector != null) {
|
||||
mScaleDetector.onTouchEvent(motionEvent);
|
||||
} else if (motionEvent.getPointerCount() == 1 && mDetector != null) {
|
||||
mDetector.onTouchEvent(motionEvent);
|
||||
}
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setOrientation(int orientation) {
|
||||
if (orientation == ORIENTATION_PORTRAIT.ordinal()) {
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
} else if (orientation == ORIENTATION_LANDSCAPE_HOME_RIGHT.ordinal()) {
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
} else if (orientation == ORIENTATION_LANDSCAPE_HOME_LEFT.ordinal()) {
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
|
||||
}
|
||||
}
|
||||
|
||||
private GestureDetector.OnGestureListener mGestureDetector = new GestureDetector.OnGestureListener() {
|
||||
@Override
|
||||
public boolean onDown(MotionEvent motionEvent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowPress(MotionEvent motionEvent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent motionEvent) {
|
||||
float x = 0f;
|
||||
float y = 0f;
|
||||
if (mAlivcLivePushConfig.getLivePushMode() == AlivcLiveMode.AlivcLiveInteractiveMode) {
|
||||
if (mPreviewContainer.getWidth() > 0 && mPreviewContainer.getHeight() > 0) {
|
||||
x = motionEvent.getX() / mPreviewContainer.getWidth();
|
||||
y = motionEvent.getY() / mPreviewContainer.getHeight();
|
||||
}
|
||||
} else {
|
||||
if (mPreviewView.getWidth() > 0 && mPreviewView.getHeight() > 0) {
|
||||
x = motionEvent.getX() / mPreviewView.getWidth();
|
||||
y = motionEvent.getY() / mPreviewView.getHeight();
|
||||
}
|
||||
}
|
||||
try {
|
||||
mAlivcLivePusher.focusCameraAtAdjustedPoint(x, y, true);
|
||||
} catch (IllegalStateException e) {
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent motionEvent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
|
||||
if (motionEvent == null || motionEvent1 == null) {
|
||||
return false;
|
||||
}
|
||||
if (motionEvent.getX() - motionEvent1.getX() > FLING_MIN_DISTANCE
|
||||
&& Math.abs(v) > FLING_MIN_VELOCITY) {
|
||||
// Fling left
|
||||
} else if (motionEvent1.getX() - motionEvent.getX() > FLING_MIN_DISTANCE
|
||||
&& Math.abs(v) > FLING_MIN_VELOCITY) {
|
||||
// Fling right
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private float scaleFactor = 1.0f;
|
||||
private ScaleGestureDetector.OnScaleGestureListener mScaleGestureDetector = new ScaleGestureDetector.OnScaleGestureListener() {
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
|
||||
if (scaleGestureDetector.getScaleFactor() > 1) {
|
||||
scaleFactor += 0.5;
|
||||
} else {
|
||||
scaleFactor -= 2;
|
||||
}
|
||||
if (scaleFactor <= 1) {
|
||||
scaleFactor = 1;
|
||||
}
|
||||
try {
|
||||
if (scaleFactor >= mAlivcLivePusher.getMaxZoom()) {
|
||||
scaleFactor = mAlivcLivePusher.getMaxZoom();
|
||||
}
|
||||
mAlivcLivePusher.setZoom((int) scaleFactor);
|
||||
|
||||
} catch (IllegalStateException e) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
SurfaceHolder.Callback mCallback = new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||
if (mSurfaceStatus == SurfaceStatus.UNINITED) {
|
||||
mSurfaceStatus = SurfaceStatus.CREATED;
|
||||
mLivePushViewModel.onSurfaceCreated(mAsync, mPreviewView, mAlivcLivePusher);
|
||||
} else if (mSurfaceStatus == SurfaceStatus.DESTROYED) {
|
||||
mSurfaceStatus = SurfaceStatus.RECREATED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
||||
mSurfaceStatus = SurfaceStatus.CHANGED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
||||
mSurfaceStatus = SurfaceStatus.DESTROYED;
|
||||
}
|
||||
};
|
||||
|
||||
public static void startActivity(Activity activity, AlivcLivePushConfig alivcLivePushConfig, String url, boolean async,
|
||||
boolean audioOnly, boolean videoOnly, AlivcPreviewOrientationEnum orientation, int cameraId, boolean isFlash,
|
||||
String authTime, String privacyKey, boolean mixExtern, boolean mixMain, boolean ischecked, int fps,
|
||||
ArrayList<WaterMarkInfo> waterMarkInfos) {
|
||||
Intent intent = new Intent(activity, LivePushActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable(AlivcLivePushConfig.CONFIG, alivcLivePushConfig);
|
||||
bundle.putString(URL_KEY, url);
|
||||
bundle.putBoolean(ASYNC_KEY, async);
|
||||
bundle.putBoolean(AUDIO_ONLY_KEY, audioOnly);
|
||||
bundle.putBoolean(VIDEO_ONLY_KEY, videoOnly);
|
||||
bundle.putInt(ORIENTATION_KEY, orientation.ordinal());
|
||||
bundle.putInt(CAMERA_ID, cameraId);
|
||||
bundle.putBoolean(FLASH_ON, isFlash);
|
||||
bundle.putString(AUTH_TIME, authTime);
|
||||
bundle.putString(PRIVACY_KEY, privacyKey);
|
||||
bundle.putBoolean(MIX_EXTERN, mixExtern);
|
||||
bundle.putBoolean(MIX_MAIN, mixMain);
|
||||
bundle.putBoolean(BEAUTY_CHECKED, ischecked);
|
||||
bundle.putInt(FPS, fps);
|
||||
bundle.putSerializable(WATER_MARK_INFOS, waterMarkInfos);
|
||||
intent.putExtras(bundle);
|
||||
activity.startActivityForResult(intent, REQ_CODE_PUSH);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (mAlivcLivePusher != null) {
|
||||
try {
|
||||
if (isPause) {
|
||||
if (mAsync) {
|
||||
mAlivcLivePusher.resumeAsync();
|
||||
} else {
|
||||
mAlivcLivePusher.resume();
|
||||
}
|
||||
mLivePushFragment.updateOperaButtonState(true);
|
||||
isPause = false;
|
||||
mAlivcLivePusher.resumeBGM();
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (mAlivcLivePusher != null) {
|
||||
try {
|
||||
if (!isPause) {
|
||||
mAlivcLivePusher.pause();
|
||||
isPause = true;
|
||||
}
|
||||
if (mLivePushFragment.isBGMPlaying()) {
|
||||
mAlivcLivePusher.pauseBGM();
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
mLivePushViewModel.stopYUV();
|
||||
mLivePushViewModel.stopPcm();
|
||||
if (mAlivcLivePusher != null) {
|
||||
try {
|
||||
mAlivcLivePusher.destroy();
|
||||
mAlivcLivePusher = null;
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
mFragmentList = null;
|
||||
mPreviewView = null;
|
||||
mViewPager = null;
|
||||
mFragmentAdapter = null;
|
||||
mDetector = null;
|
||||
mScaleDetector = null;
|
||||
mLivePushFragment = null;
|
||||
mAlivcLivePushConfig = null;
|
||||
mAlivcLivePusher = null;
|
||||
alivcLivePushStatsInfo = null;
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
public class FragmentAdapter extends FragmentPagerAdapter {
|
||||
|
||||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
|
||||
public FragmentAdapter(FragmentManager fm, List<Fragment> fragmentList) {
|
||||
super(fm);
|
||||
this.fragmentList = fragmentList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return fragmentList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return fragmentList.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
int rotation = getWindowManager().getDefaultDisplay().getRotation();
|
||||
AlivcPreviewOrientationEnum orientationEnum;
|
||||
if (mAlivcLivePusher != null) {
|
||||
switch (rotation) {
|
||||
case Surface.ROTATION_0:
|
||||
orientationEnum = ORIENTATION_PORTRAIT;
|
||||
break;
|
||||
case Surface.ROTATION_90:
|
||||
orientationEnum = ORIENTATION_LANDSCAPE_HOME_RIGHT;
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
orientationEnum = ORIENTATION_LANDSCAPE_HOME_LEFT;
|
||||
break;
|
||||
default:
|
||||
orientationEnum = ORIENTATION_PORTRAIT;
|
||||
break;
|
||||
}
|
||||
try {
|
||||
mAlivcLivePusher.setPreviewOrientation(orientationEnum);
|
||||
} catch (IllegalStateException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlivcLivePusher getLivePusher() {
|
||||
return this.mAlivcLivePusher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PauseState getPauseStateListener() {
|
||||
return this.mStateListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceView getPreviewView() {
|
||||
return this.mPreviewView;
|
||||
}
|
||||
|
||||
private void showDialog(Context context, String message) {
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
|
||||
dialog.setTitle(getString(R.string.dialog_title));
|
||||
dialog.setMessage(message);
|
||||
dialog.setNegativeButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public interface PauseState {
|
||||
void updatePause(boolean state);
|
||||
}
|
||||
|
||||
private PauseState mStateListener = new PauseState() {
|
||||
@Override
|
||||
public void updatePause(boolean state) {
|
||||
isPause = state;
|
||||
}
|
||||
};
|
||||
|
||||
public static class ConnectivityChangedReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
|
||||
|
||||
if (mNetWork != NetWorkUtils.getAPNType(context)) {
|
||||
mNetWork = NetWorkUtils.getAPNType(context);
|
||||
if (mAlivcLivePusher != null) {
|
||||
if (mAlivcLivePusher.isPushing()) {
|
||||
try {
|
||||
mAlivcLivePusher.reconnectPushAsync(null);
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,1416 @@
|
||||
package com.alivc.live.baselive_push.ui;
|
||||
|
||||
import static com.alivc.live.pusher.AlivcLivePushCameraTypeEnum.CAMERA_TYPE_BACK;
|
||||
import static com.alivc.live.pusher.AlivcLivePushCameraTypeEnum.CAMERA_TYPE_FRONT;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Bitmap;
|
||||
import android.hardware.Camera;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.alivc.component.custom.AlivcLivePushCustomFilter;
|
||||
import com.alivc.live.annotations.AlivcLiveConnectionStatus;
|
||||
import com.alivc.live.annotations.AlivcLiveConnectionStatusChangeReason;
|
||||
import com.alivc.live.annotations.AlivcLiveMode;
|
||||
import com.alivc.live.annotations.AlivcLiveNetworkQuality;
|
||||
import com.alivc.live.annotations.AlivcLivePushKickedOutType;
|
||||
import com.alivc.live.annotations.AlivcLiveRecordAudioQuality;
|
||||
import com.alivc.live.annotations.AlivcLiveRecordMediaEvent;
|
||||
import com.alivc.live.annotations.AlivcLiveRecordMediaFormat;
|
||||
import com.alivc.live.annotations.AlivcLiveRecordStreamType;
|
||||
import com.alivc.live.commonbiz.testapi.EGLContextTest;
|
||||
import com.alivc.live.commonui.dialog.CommonDialog;
|
||||
import com.alivc.live.commonui.messageview.AutoScrollMessagesView;
|
||||
import com.alivc.live.commonui.seiview.LivePusherSEIView;
|
||||
import com.alivc.live.commonui.widgets.LivePushTextSwitch;
|
||||
import com.alivc.live.baselive_push.R;
|
||||
import com.alivc.live.baselive_push.adapter.IPushController;
|
||||
import com.alivc.live.baselive_push.adapter.OnSoundEffectChangedListener;
|
||||
import com.alivc.live.baselive_push.ui.widget.PushMoreConfigBottomSheetLive;
|
||||
import com.alivc.live.baselive_push.ui.widget.PushMusicBottomSheetLive;
|
||||
import com.alivc.live.baselive_push.ui.widget.SoundEffectView;
|
||||
import com.alivc.live.beauty.BeautyFactory;
|
||||
import com.alivc.live.beauty.BeautyInterface;
|
||||
import com.alivc.live.beauty.constant.BeautySDKType;
|
||||
import com.alivc.live.commonbiz.SharedPreferenceUtils;
|
||||
import com.alivc.live.commonutils.FastClickUtil;
|
||||
import com.alivc.live.commonutils.FileUtil;
|
||||
import com.alivc.live.commonutils.TextFormatUtil;
|
||||
import com.alivc.live.commonutils.ToastUtils;
|
||||
import com.alivc.live.player.annotations.AlivcLivePlayVideoStreamType;
|
||||
import com.alivc.live.pusher.AlivcLiveLocalRecordConfig;
|
||||
import com.alivc.live.pusher.AlivcLiveNetworkQualityProbeConfig;
|
||||
import com.alivc.live.pusher.AlivcLiveNetworkQualityProbeResult;
|
||||
import com.alivc.live.pusher.AlivcLivePublishState;
|
||||
import com.alivc.live.pusher.AlivcLivePushAudioEffectReverbMode;
|
||||
import com.alivc.live.pusher.AlivcLivePushAudioEffectVoiceChangeMode;
|
||||
import com.alivc.live.pusher.AlivcLivePushBGMListener;
|
||||
import com.alivc.live.pusher.AlivcLivePushConfig;
|
||||
import com.alivc.live.pusher.AlivcLivePushError;
|
||||
import com.alivc.live.pusher.AlivcLivePushErrorListener;
|
||||
import com.alivc.live.pusher.AlivcLivePushInfoListener;
|
||||
import com.alivc.live.pusher.AlivcLivePushNetworkListener;
|
||||
import com.alivc.live.pusher.AlivcLivePushStatsInfo;
|
||||
import com.alivc.live.pusher.AlivcLivePusher;
|
||||
import com.alivc.live.pusher.AlivcPreviewDisplayMode;
|
||||
import com.alivc.live.pusher.AlivcResolutionEnum;
|
||||
import com.alivc.live.pusher.AlivcSnapshotListener;
|
||||
import com.alivc.live.pusher.WaterMarkInfo;
|
||||
import com.aliyunsdk.queen.menu.QueenBeautyMenu;
|
||||
import com.aliyunsdk.queen.menu.QueenMenuPanel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
|
||||
public class LivePushFragment extends Fragment {
|
||||
public static final String TAG = "LivePushFragment";
|
||||
|
||||
private static final String PUSH_CONFIG = "push_config";
|
||||
private static final String URL_KEY = "url_key";
|
||||
private static final String ASYNC_KEY = "async_key";
|
||||
private static final String AUDIO_ONLY_KEY = "audio_only_key";
|
||||
private static final String VIDEO_ONLY_KEY = "video_only_key";
|
||||
private static final String QUALITY_MODE_KEY = "quality_mode_key";
|
||||
private static final String CAMERA_ID = "camera_id";
|
||||
private static final String FLASH_ON = "flash_on";
|
||||
private static final String AUTH_TIME = "auth_time";
|
||||
private static final String PRIVACY_KEY = "privacy_key";
|
||||
private static final String MIX_EXTERN = "mix_extern";
|
||||
private static final String MIX_MAIN = "mix_main";
|
||||
private static final String BEAUTY_CHECKED = "beauty_checked";
|
||||
private static final String FPS = "fps";
|
||||
private static final String PREVIEW_ORIENTATION = "preview_orientation";
|
||||
private static final String WATER_MARK_INFOS = "water_mark";
|
||||
private ImageView mExit;
|
||||
private View mMusic;
|
||||
private View mFlash;
|
||||
private View mCamera;
|
||||
private View mSnapshot;
|
||||
private View mBeautyButton;
|
||||
private View mSoundEffectButton;
|
||||
|
||||
private TextView mPreviewButton;
|
||||
private TextView mPushButton;
|
||||
private TextView mOperaButton;
|
||||
private TextView mMore;
|
||||
private TextView mRestartButton;
|
||||
private TextView mDataButton;
|
||||
private TextView mNetworkDetectButton;
|
||||
|
||||
private AlivcLivePushConfig mAlivcLivePushConfig = null;
|
||||
private String mPushUrl = null;
|
||||
private boolean mAsync = false;
|
||||
|
||||
private boolean mAudio = false;
|
||||
private boolean mVideoOnly = false;
|
||||
|
||||
private int mCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
|
||||
private boolean isFlash = false;
|
||||
private boolean mMixExtern = false;
|
||||
private boolean mMixMain = false;
|
||||
private boolean flashState = true;
|
||||
|
||||
private int snapshotCount = 0;
|
||||
|
||||
private int mQualityMode = 0;
|
||||
|
||||
ScheduledExecutorService mExecutorService = new ScheduledThreadPoolExecutor(5);
|
||||
private boolean mIsStartAsnycPushing = false;
|
||||
|
||||
private PushMusicBottomSheetLive mMusicDialog = null;
|
||||
|
||||
private String mAuthString = "?auth_key=%1$d-%2$d-%3$d-%4$s";
|
||||
private String mMd5String = "%1$s-%2$d-%3$d-%4$d-%5$s";
|
||||
private String mTempUrl = null;
|
||||
private String mAuthTime = "";
|
||||
private String mPrivacyKey = "";
|
||||
private TextView mStatusTV;
|
||||
private LinearLayout mActionBar;
|
||||
Vector<Integer> mDynamicals = new Vector<>();
|
||||
// 高级美颜管理类
|
||||
private BeautyInterface mBeautyManager;
|
||||
private boolean isBeautyEnable = true;
|
||||
private int mCurBr;
|
||||
private int mTargetBr;
|
||||
private boolean mBeautyOn = true;
|
||||
private int mFps;
|
||||
private int mPreviewOrientation;
|
||||
private CommonDialog mDialog;
|
||||
private boolean isConnectResult = false;//是否正在链接中
|
||||
private QueenBeautyMenu mBeautyBeautyContainerView;
|
||||
|
||||
private QueenMenuPanel mQueenMenuPanel;
|
||||
private IPushController mPushController = null;
|
||||
private ArrayList<WaterMarkInfo> waterMarkInfos = null;
|
||||
//音效
|
||||
private SoundEffectView mSoundEffectView;
|
||||
|
||||
private LivePushViewModel mLivePushViewModel;
|
||||
private LivePusherSEIView mSeiView;
|
||||
private LivePushTextSwitch mShowCustomMessageView;
|
||||
private LivePushTextSwitch mLocalRecordView;
|
||||
private AlivcResolutionEnum mCurrentResolution;
|
||||
|
||||
private AutoScrollMessagesView mMessagesView;
|
||||
private boolean isShowStatistics = false;
|
||||
|
||||
private TextView mManualCreateEGLContextTv;
|
||||
|
||||
private boolean mIsBGMPlaying = false;
|
||||
|
||||
public static LivePushFragment newInstance(AlivcLivePushConfig livePushConfig, String url, boolean async, boolean mAudio, boolean mVideoOnly, int cameraId,
|
||||
boolean isFlash, int mode, String authTime, String privacyKey, boolean mixExtern,
|
||||
boolean mixMain, boolean beautyOn, int fps, int previewOrientation,
|
||||
ArrayList<WaterMarkInfo> waterMarkInfos) {
|
||||
LivePushFragment livePushFragment = new LivePushFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable(PUSH_CONFIG, livePushConfig);
|
||||
bundle.putString(URL_KEY, url);
|
||||
bundle.putBoolean(ASYNC_KEY, async);
|
||||
bundle.putBoolean(AUDIO_ONLY_KEY, mAudio);
|
||||
bundle.putBoolean(VIDEO_ONLY_KEY, mVideoOnly);
|
||||
bundle.putInt(QUALITY_MODE_KEY, mode);
|
||||
bundle.putInt(CAMERA_ID, cameraId);
|
||||
bundle.putBoolean(FLASH_ON, isFlash);
|
||||
bundle.putString(AUTH_TIME, authTime);
|
||||
bundle.putString(PRIVACY_KEY, privacyKey);
|
||||
bundle.putBoolean(MIX_EXTERN, mixExtern);
|
||||
bundle.putBoolean(MIX_MAIN, mixMain);
|
||||
bundle.putBoolean(BEAUTY_CHECKED, beautyOn);
|
||||
bundle.putInt(FPS, fps);
|
||||
bundle.putInt(PREVIEW_ORIENTATION, previewOrientation);
|
||||
bundle.putSerializable(WATER_MARK_INFOS, waterMarkInfos);
|
||||
livePushFragment.setArguments(bundle);
|
||||
return livePushFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
|
||||
if (context instanceof IPushController) {
|
||||
mPushController = (IPushController) context;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//Fragment may be recreated, so move all init logic to onActivityCreated
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
mLivePushViewModel = new ViewModelProvider(getActivity()).get(LivePushViewModel.class);
|
||||
|
||||
AlivcLivePusher pusher = mPushController.getLivePusher();
|
||||
if (getArguments() != null) {
|
||||
mAlivcLivePushConfig = (AlivcLivePushConfig) getArguments().getSerializable(PUSH_CONFIG);
|
||||
mPushUrl = getArguments().getString(URL_KEY);
|
||||
mAsync = getArguments().getBoolean(ASYNC_KEY, false);
|
||||
mAudio = getArguments().getBoolean(AUDIO_ONLY_KEY, false);
|
||||
mVideoOnly = getArguments().getBoolean(VIDEO_ONLY_KEY, false);
|
||||
mCameraId = getArguments().getInt(CAMERA_ID);
|
||||
isFlash = getArguments().getBoolean(FLASH_ON, false);
|
||||
mMixExtern = getArguments().getBoolean(MIX_EXTERN, false);
|
||||
mMixMain = getArguments().getBoolean(MIX_MAIN, false);
|
||||
mQualityMode = getArguments().getInt(QUALITY_MODE_KEY);
|
||||
mBeautyOn = getArguments().getBoolean(BEAUTY_CHECKED);
|
||||
mFps = getArguments().getInt(FPS);
|
||||
mPreviewOrientation = getArguments().getInt(PREVIEW_ORIENTATION);
|
||||
waterMarkInfos = (ArrayList<WaterMarkInfo>) getArguments().getSerializable(WATER_MARK_INFOS);
|
||||
flashState = isFlash;
|
||||
}
|
||||
if (pusher != null) {
|
||||
pusher.setLivePushInfoListener(mPushInfoListener);
|
||||
pusher.setLivePushErrorListener(mPushErrorListener);
|
||||
pusher.setLivePushNetworkListener(mPushNetworkListener);
|
||||
pusher.setLivePushBGMListener(mPushBGMListener);
|
||||
}
|
||||
|
||||
if (mAlivcLivePushConfig.isExternMainStream()) {
|
||||
mLivePushViewModel.startPCM(pusher);
|
||||
mLivePushViewModel.startYUV(pusher);
|
||||
}
|
||||
|
||||
if (pusher != null && (mBeautyOn)) {
|
||||
pusher.setCustomFilter(new AlivcLivePushCustomFilter() {
|
||||
@Override
|
||||
public void customFilterCreate() {
|
||||
sendLogToMessageView("[CBK][CustomFilter] customFilterCreate: [" + Thread.currentThread().getId() + "]");
|
||||
sendLogToMessageView("推流地址:"+mPushUrl);
|
||||
initBeautyManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int customFilterProcess(int inputTexture, int textureWidth, int textureHeight, long extra) {
|
||||
if (mBeautyManager == null) {
|
||||
return inputTexture;
|
||||
}
|
||||
|
||||
return mBeautyManager.onTextureInput(inputTexture, textureWidth, textureHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customFilterDestroy() {
|
||||
destroyBeautyManager();
|
||||
sendLogToMessageView("[CBK][CustomFilter] customFilterDestroy: [" + Thread.currentThread().getId() + "]");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.push_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
mQueenMenuPanel = QueenBeautyMenu.getPanel(this.getContext());
|
||||
mQueenMenuPanel.onHideMenu();
|
||||
mQueenMenuPanel.onHideValidFeatures();
|
||||
mQueenMenuPanel.onHideCopyright();
|
||||
|
||||
mMessagesView = view.findViewById(R.id.v_messages);
|
||||
sendLogToMessageView("----------statistics info----------");
|
||||
|
||||
mBeautyBeautyContainerView = view.findViewById(R.id.beauty_beauty_menuPanel);
|
||||
mBeautyBeautyContainerView.addView(mQueenMenuPanel);
|
||||
|
||||
mSoundEffectView = view.findViewById(R.id.sound_effect_view);
|
||||
|
||||
// 发送SEI
|
||||
mSeiView = view.findViewById(R.id.sei_view);
|
||||
mSeiView.setSendSeiViewListener((payload, text) -> mPushController.getLivePusher().sendMessage(text, 0, 0, true));
|
||||
|
||||
mShowCustomMessageView = view.findViewById(R.id.btn_show_custom_message);
|
||||
mShowCustomMessageView.setTextViewText(getString(R.string.sei_send_custom_message_tv));
|
||||
mShowCustomMessageView.setOnSwitchToggleListener(isChecked -> {
|
||||
int visibility = isChecked ? View.VISIBLE : View.GONE;
|
||||
mSeiView.setVisibility(visibility);
|
||||
});
|
||||
|
||||
// 本地录制
|
||||
mLocalRecordView = view.findViewById(R.id.btn_local_record);
|
||||
mLocalRecordView.setTextViewText(getString(R.string.local_record_tv));
|
||||
mLocalRecordView.setOnSwitchToggleListener(isChecked -> {
|
||||
AlivcLivePusher livePusher = mPushController.getLivePusher();
|
||||
if (livePusher == null) {
|
||||
return;
|
||||
}
|
||||
if (isChecked) {
|
||||
AlivcLiveLocalRecordConfig recordConfig = new AlivcLiveLocalRecordConfig();
|
||||
String dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
|
||||
recordConfig.storagePath = FileUtil.getExternalCacheFolder(getContext()) + "/" + dateFormat + ".mp4";
|
||||
recordConfig.streamType = AlivcLiveRecordStreamType.AUDIO_VIDEO;
|
||||
recordConfig.audioQuality = AlivcLiveRecordAudioQuality.MEDIUM;
|
||||
recordConfig.mediaFormat = AlivcLiveRecordMediaFormat.MP4;
|
||||
livePusher.startLocalRecord(recordConfig);
|
||||
} else {
|
||||
livePusher.stopLocalRecord();
|
||||
}
|
||||
});
|
||||
|
||||
mManualCreateEGLContextTv = view.findViewById(R.id.tv_manual_create_egl_context);
|
||||
mManualCreateEGLContextTv.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Thread thread = new Thread(() -> EGLContextTest.testGLContext());
|
||||
sendLogToMessageView("Manual Create EGLContext: " + thread.getName());
|
||||
thread.start();
|
||||
}
|
||||
});
|
||||
|
||||
mSoundEffectView.setOnSoundEffectChangedListener(new OnSoundEffectChangedListener() {
|
||||
@Override
|
||||
public void onSoundEffectChangeVoiceModeSelected(int position) {
|
||||
if (position >= 0 && position < AlivcLivePushAudioEffectVoiceChangeMode.values().length) {
|
||||
AlivcLivePusher livePusher = mPushController.getLivePusher();
|
||||
Log.d(TAG, "onSoundEffectChangeVoiceModeSelected: " + position + " --- " + AlivcLivePushAudioEffectVoiceChangeMode.values()[position]);
|
||||
livePusher.setAudioEffectVoiceChangeMode(AlivcLivePushAudioEffectVoiceChangeMode.values()[position]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSoundEffectRevertBSelected(int position) {
|
||||
if (position >= 0 && position < AlivcLivePushAudioEffectReverbMode.values().length) {
|
||||
AlivcLivePusher livePusher = mPushController.getLivePusher();
|
||||
Log.d(TAG, "onSoundEffectRevertBSelected: " + position + " --- " + AlivcLivePushAudioEffectReverbMode.values()[position]);
|
||||
livePusher.setAudioEffectReverbMode(AlivcLivePushAudioEffectReverbMode.values()[position]);
|
||||
}
|
||||
}
|
||||
});
|
||||
mDataButton = (TextView) view.findViewById(R.id.data);
|
||||
mNetworkDetectButton = (TextView) view.findViewById(R.id.network_detect);
|
||||
mStatusTV = (TextView) view.findViewById(R.id.tv_status);
|
||||
mExit = (ImageView) view.findViewById(R.id.exit);
|
||||
mMusic = view.findViewById(R.id.music);
|
||||
mFlash = view.findViewById(R.id.flash);
|
||||
mFlash.setSelected(isFlash);
|
||||
mCamera = view.findViewById(R.id.camera);
|
||||
mSnapshot = view.findViewById(R.id.snapshot);
|
||||
mActionBar = (LinearLayout) view.findViewById(R.id.action_bar);
|
||||
mCamera.setSelected(true);
|
||||
mSnapshot.setSelected(true);
|
||||
mPreviewButton = view.findViewById(R.id.preview_button);
|
||||
mPreviewButton.setSelected(true);
|
||||
mPushButton = view.findViewById(R.id.push_button);
|
||||
mPushButton.setSelected(false);
|
||||
mOperaButton = view.findViewById(R.id.opera_button);
|
||||
mOperaButton.setSelected(false);
|
||||
mMore = (TextView) view.findViewById(R.id.more);
|
||||
mBeautyButton = view.findViewById(R.id.beauty_button);
|
||||
mBeautyButton.setSelected(SharedPreferenceUtils.isBeautyOn(getActivity().getApplicationContext()));
|
||||
mSoundEffectButton = view.findViewById(R.id.sound_effect_button);
|
||||
mRestartButton = (TextView) view.findViewById(R.id.restart_button);
|
||||
mExit.setOnClickListener(onClickListener);
|
||||
mMusic.setOnClickListener(onClickListener);
|
||||
mFlash.setOnClickListener(onClickListener);
|
||||
|
||||
mCamera.setOnClickListener(onClickListener);
|
||||
mSnapshot.setOnClickListener(onClickListener);
|
||||
mPreviewButton.setOnClickListener(onClickListener);
|
||||
mSoundEffectButton.setOnClickListener(onClickListener);
|
||||
mPushButton.setOnClickListener(onClickListener);
|
||||
mOperaButton.setOnClickListener(onClickListener);
|
||||
mBeautyButton.setOnClickListener(onClickListener);
|
||||
mRestartButton.setOnClickListener(onClickListener);
|
||||
mMore.setOnClickListener(onClickListener);
|
||||
mDataButton.setOnClickListener(onClickListener);
|
||||
mNetworkDetectButton.setOnClickListener(onClickListener);
|
||||
|
||||
if (mVideoOnly) {
|
||||
mMusic.setVisibility(View.GONE);
|
||||
}
|
||||
if (mAudio) {
|
||||
mPreviewButton.setVisibility(View.GONE);
|
||||
}
|
||||
if (mMixMain) {
|
||||
mBeautyButton.setVisibility(View.GONE);
|
||||
mMusic.setVisibility(View.GONE);
|
||||
mFlash.setVisibility(View.GONE);
|
||||
mCamera.setVisibility(View.GONE);
|
||||
}
|
||||
mMore.setVisibility(mAudio ? View.GONE : View.VISIBLE);
|
||||
mBeautyButton.setVisibility(mAudio ? View.GONE : View.VISIBLE);
|
||||
mFlash.setVisibility(mAudio ? View.GONE : View.VISIBLE);
|
||||
mCamera.setVisibility(mAudio ? View.GONE : View.VISIBLE);
|
||||
mFlash.setClickable(mCameraId != CAMERA_TYPE_FRONT.getCameraId());
|
||||
view.setFocusableInTouchMode(true);
|
||||
view.requestFocus();
|
||||
view.setOnKeyListener(new View.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if (mPushButton.isSelected() && !isConnectResult) {
|
||||
showDialog(getSafeString(R.string.connecting_dialog_tips));
|
||||
} else {
|
||||
getActivity().finish();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
View.OnClickListener onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
final int id = view.getId();
|
||||
AlivcLivePusher pusher = mPushController.getLivePusher();
|
||||
if (pusher == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == R.id.music) {
|
||||
if (!mAlivcLivePushConfig.isVideoOnly()) {
|
||||
if (mMusicDialog == null) {
|
||||
mMusicDialog = new PushMusicBottomSheetLive(getContext());
|
||||
mMusicDialog.setOnMusicSelectListener(new PushMusicBottomSheetLive.OnMusicSelectListener() {
|
||||
@Override
|
||||
public void onBGMEarsBack(boolean state) {
|
||||
pusher.setBGMEarsBack(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioNoise(boolean state) {
|
||||
pusher.setAudioDenoise(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEarphone(boolean state) {
|
||||
pusher.enableSpeakerphone(!state);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启音频智能降噪(使用智能降噪须知)
|
||||
* <p>
|
||||
* 1、使用智能降噪,请关闭普通降噪;两者功能互斥使用
|
||||
* 2、智能降噪功能以插件形式提供,调用该接口前,请确保已集成了libpluginAliDenoise.so;插件获取方式请参考官网文档;
|
||||
* 3、此接口可以通话过程中控制打开智能降噪功能,通话过程中可以支持开启和关闭智能降噪
|
||||
* 4、默认关闭,开启后可能导致功耗增加,智能降噪适合于会议,教育等语音通讯为主的场景,不适合有背景音乐的场景
|
||||
* <p>
|
||||
* 注意事项!!!
|
||||
* 如遇libMNN相关的so冲突,请检查当前工程中是否使用到了视频云的其它产品,如美颜SDK/Animoji SDK
|
||||
* 美颜SDK/Animoji SDK中,包含libMNN相关的so,因此外部无需再导入一份,只保留libpluginAliDenoise.so,
|
||||
* 全局MNN相关的库,统一留一份即可;
|
||||
* 具体请查看官网文档或API文档,或者您可以咨询技术同学协助解决问题;
|
||||
*
|
||||
* @see <a href="https://help.aliyun.com/zh/live/developer-reference/push-sdk/">推流SDK(新版)官网文档</a>
|
||||
*/
|
||||
@Override
|
||||
public void onAudioIntelligentNoise(boolean state) {
|
||||
int result = 0;
|
||||
if (state) {
|
||||
result = pusher.startIntelligentDenoise();
|
||||
} else {
|
||||
result = pusher.stopIntelligentDenoise();
|
||||
}
|
||||
ToastUtils.show(result == 0 ? getSafeString(R.string.success) : getSafeString(R.string.failed));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBGPlay(boolean state) {
|
||||
if (state) {
|
||||
pusher.resumeBGM();
|
||||
} else {
|
||||
pusher.pauseBGM();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBgResource(String path) {
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
pusher.startBGMAsync(path);
|
||||
if (mAlivcLivePushConfig.getLivePushMode() == AlivcLiveMode.AlivcLiveInteractiveMode) {
|
||||
//互动模式,开启 bgm 后,需要设置音量,否则没有声音
|
||||
pusher.setBGMVolume(50);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
pusher.stopBGMAsync();
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBGLoop(boolean state) {
|
||||
pusher.setBGMLoop(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMute(boolean state) {
|
||||
pusher.setMute(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCaptureVolume(int progress) {
|
||||
pusher.setCaptureVolume(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBGMVolume(int progress) {
|
||||
pusher.setBGMVolume(progress);
|
||||
}
|
||||
});
|
||||
}
|
||||
mMusicDialog.show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LivePushActivity.PauseState stateListener = mPushController.getPauseStateListener();
|
||||
try {
|
||||
if (id == R.id.exit) {
|
||||
if (mPushButton.isSelected() && !isConnectResult) {
|
||||
showDialog(getSafeString(R.string.connecting_dialog_tips));
|
||||
return;
|
||||
}
|
||||
getActivity().finish();
|
||||
} else if (id == R.id.flash) {
|
||||
pusher.setFlash(!mFlash.isSelected());
|
||||
flashState = !mFlash.isSelected();
|
||||
mFlash.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mFlash.setSelected(!mFlash.isSelected());
|
||||
}
|
||||
});
|
||||
} else if (id == R.id.camera) {
|
||||
if (FastClickUtil.isProcessing()) {
|
||||
return;
|
||||
}
|
||||
if (mCameraId == CAMERA_TYPE_FRONT.getCameraId()) {
|
||||
mCameraId = CAMERA_TYPE_BACK.getCameraId();
|
||||
} else {
|
||||
mCameraId = CAMERA_TYPE_FRONT.getCameraId();
|
||||
}
|
||||
pusher.switchCamera();
|
||||
if (mBeautyManager != null) {
|
||||
mBeautyManager.switchCameraId(mCameraId);
|
||||
}
|
||||
mFlash.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mFlash.setClickable(mCameraId != CAMERA_TYPE_FRONT.getCameraId());
|
||||
if (mCameraId == CAMERA_TYPE_FRONT.getCameraId()) {
|
||||
mFlash.setSelected(false);
|
||||
} else {
|
||||
mFlash.setSelected(flashState);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (id == R.id.preview_button) {
|
||||
if (FastClickUtil.isProcessing()) {
|
||||
return;
|
||||
}
|
||||
final boolean isPreview = mPreviewButton.isSelected();
|
||||
if (isPreview) {
|
||||
pusher.stopPreview();
|
||||
} else {
|
||||
SurfaceView previewView = mPushController.getPreviewView();
|
||||
if (mAsync) {
|
||||
pusher.startPreviewAsync(previewView);
|
||||
} else {
|
||||
pusher.startPreview(previewView);
|
||||
}
|
||||
}
|
||||
|
||||
mPreviewButton.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mPreviewButton.setText(isPreview ? getSafeString(R.string.start_preview_button) : getSafeString(R.string.stop_preview_button));
|
||||
mPreviewButton.setSelected(!isPreview);
|
||||
}
|
||||
});
|
||||
} else if (id == R.id.push_button) {
|
||||
final boolean isPush = mPushButton.isSelected();
|
||||
if (!isPush) {
|
||||
if (mAsync) {
|
||||
pusher.startPushAsync(mPushUrl);
|
||||
} else {
|
||||
pusher.startPush(mPushUrl);
|
||||
}
|
||||
} else {
|
||||
pusher.stopPush();
|
||||
mOperaButton.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mOperaButton.setText(getSafeString(R.string.pause_button));
|
||||
mOperaButton.setSelected(false);
|
||||
}
|
||||
});
|
||||
if (stateListener != null) {
|
||||
stateListener.updatePause(false);
|
||||
}
|
||||
}
|
||||
|
||||
mPushButton.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mStatusTV.setText(isPush ? getSafeString(R.string.wating_push) : getSafeString(R.string.pushing));
|
||||
mPushButton.setText(isPush ? getSafeString(R.string.start_push) : getSafeString(R.string.stop_button));
|
||||
mPushButton.setSelected(!isPush);
|
||||
}
|
||||
});
|
||||
} else if (id == R.id.opera_button) {
|
||||
final boolean isPause = mOperaButton.isSelected();
|
||||
if (!isPause) {
|
||||
pusher.pause();
|
||||
} else {
|
||||
if (mAsync) {
|
||||
pusher.resumeAsync();
|
||||
} else {
|
||||
pusher.resume();
|
||||
}
|
||||
}
|
||||
|
||||
if (stateListener != null) {
|
||||
stateListener.updatePause(!isPause);
|
||||
}
|
||||
updateOperaButtonState(isPause);
|
||||
} else if (id == R.id.sound_effect_button) {
|
||||
if (!mAlivcLivePushConfig.isVideoOnly()) {
|
||||
mSoundEffectView.post(() -> {
|
||||
if (mBeautyBeautyContainerView.getVisibility() == View.VISIBLE) {
|
||||
changeBeautyContainerVisibility();
|
||||
}
|
||||
changeSoundEffectVisibility();
|
||||
});
|
||||
}
|
||||
} else if (id == R.id.beauty_button) {
|
||||
if (!mBeautyOn) {
|
||||
ToastUtils.show(getSafeString(R.string.beauty_off_tips));
|
||||
return;
|
||||
}
|
||||
if (!mAlivcLivePushConfig.isAudioOnly()) {
|
||||
mBeautyButton.post(() -> {
|
||||
if (mSoundEffectView.getVisibility() == View.VISIBLE) {
|
||||
changeSoundEffectVisibility();
|
||||
}
|
||||
changeBeautyContainerVisibility();
|
||||
});
|
||||
}
|
||||
} else if (id == R.id.restart_button) {
|
||||
if (mAsync) {
|
||||
if (!mIsStartAsnycPushing) {
|
||||
mIsStartAsnycPushing = true;
|
||||
pusher.restartPushAsync();
|
||||
}
|
||||
} else {
|
||||
pusher.restartPush();
|
||||
}
|
||||
} else if (id == R.id.more) {
|
||||
mMore.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PushMoreConfigBottomSheetLive pushMoreDialog = new PushMoreConfigBottomSheetLive(getActivity(), R.style.Live_BottomSheetDialog);
|
||||
pushMoreDialog.setOnMoreConfigListener(new PushMoreConfigBottomSheetLive.OnMoreConfigListener() {
|
||||
|
||||
@Override
|
||||
public void onDisplayModeChanged(AlivcPreviewDisplayMode mode) {
|
||||
pusher.setPreviewMode(mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPushMirror(boolean state) {
|
||||
pusher.setPushMirror(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreviewMirror(boolean state) {
|
||||
pusher.setPreviewMirror(state);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutoFocus(boolean state) {
|
||||
pusher.setAutoFocus(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAddDynamic() {
|
||||
if (mDynamicals.size() < 5) {
|
||||
float startX = 0.1f + mDynamicals.size() * 0.2f;
|
||||
float startY = 0.1f + mDynamicals.size() * 0.2f;
|
||||
int id = pusher.addDynamicsAddons(getActivity().getFilesDir().getPath() + File.separator + "alivc_resource/qizi/", startX, startY, 0.2f, 0.2f);
|
||||
if (id > 0) {
|
||||
mDynamicals.add(id);
|
||||
} else {
|
||||
ToastUtils.show(getSafeString(R.string.add_dynamic_failed) + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveDynamic() {
|
||||
if (mDynamicals.size() > 0) {
|
||||
int index = mDynamicals.size() - 1;
|
||||
int id = mDynamicals.get(index);
|
||||
pusher.removeDynamicsAddons(id);
|
||||
mDynamicals.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResolutionChanged(AlivcResolutionEnum resolutionEnum) {
|
||||
mCurrentResolution = resolutionEnum;
|
||||
if (resolutionEnum != AlivcResolutionEnum.RESOLUTION_SELF_DEFINE) {
|
||||
pusher.changeResolution(resolutionEnum);
|
||||
}
|
||||
}
|
||||
});
|
||||
pushMoreDialog.setOnDismissListener(dialogInterface -> {
|
||||
if (mCurrentResolution == AlivcResolutionEnum.RESOLUTION_SELF_DEFINE) {
|
||||
AlivcResolutionEnum.RESOLUTION_SELF_DEFINE.setSelfDefineResolution(pushMoreDialog.getResolutionWidth(), pushMoreDialog.getResolutionHeight());
|
||||
pusher.changeResolution(AlivcResolutionEnum.RESOLUTION_SELF_DEFINE);
|
||||
}
|
||||
});
|
||||
pushMoreDialog.setQualityMode(mQualityMode);
|
||||
pushMoreDialog.show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// PushMoreDialog pushMoreDialog = new PushMoreDialog();
|
||||
// pushMoreDialog.setAlivcLivePusher(pusher, new DynamicListener() {
|
||||
// @Override
|
||||
// public void onAddDynamic() {
|
||||
// if (mDynamicals.size() < 5) {
|
||||
// float startX = 0.1f + mDynamicals.size() * 0.2f;
|
||||
// float startY = 0.1f + mDynamicals.size() * 0.2f;
|
||||
// int id = pusher.addDynamicsAddons(getActivity().getFilesDir().getPath() + File.separator + "alivc_resource/qizi/", startX, startY, 0.2f, 0.2f);
|
||||
// if (id > 0) {
|
||||
// mDynamicals.add(id);
|
||||
// } else {
|
||||
// ToastUtils.show(getSafeString(R.string.add_dynamic_failed) + id);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onRemoveDynamic() {
|
||||
// if (mDynamicals.size() > 0) {
|
||||
// int index = mDynamicals.size() - 1;
|
||||
// int id = mDynamicals.get(index);
|
||||
// pusher.removeDynamicsAddons(id);
|
||||
// mDynamicals.remove(index);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// pushMoreDialog.setQualityMode(mQualityMode);
|
||||
// pushMoreDialog.setPushUrl(mPushUrl);
|
||||
// pushMoreDialog.show(getFragmentManager(), "moreDialog");
|
||||
} else if (id == R.id.snapshot) {
|
||||
pusher.snapshot(1, 0, new AlivcSnapshotListener() {
|
||||
@Override
|
||||
public void onSnapshot(Bitmap bmp) {
|
||||
String dateFormat = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss-SS").format(new Date());
|
||||
File f = new File(getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES), "snapshot-" + dateFormat + ".png");
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
showDialog("截图已保存:" + getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES).getPath() + "/snapshot-" + dateFormat + ".png");
|
||||
}
|
||||
});
|
||||
} else if (id == R.id.data) {
|
||||
isShowStatistics = !isShowStatistics;
|
||||
ToastUtils.show((isShowStatistics ? "open" : "close") + " statistics info");
|
||||
} else if (id == R.id.network_detect) {
|
||||
if (pusher != null) {
|
||||
boolean isSelect = mNetworkDetectButton.isSelected();
|
||||
if (isSelect) {
|
||||
int result = pusher.stopLastMileDetect();
|
||||
sendLogToMessageView("[API] stopLastMileDetect: [end][" + result + "]");
|
||||
} else {
|
||||
AlivcLiveNetworkQualityProbeConfig probeConfig = new AlivcLiveNetworkQualityProbeConfig();
|
||||
probeConfig.probeUpLink = true;
|
||||
probeConfig.probeDownLink = true;
|
||||
int result = pusher.startLastMileDetect(probeConfig);
|
||||
sendLogToMessageView("[API] startLastMileDetect: [end][" + result + "][" + probeConfig + "]");
|
||||
}
|
||||
mNetworkDetectButton.setSelected(!isSelect);
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
showDialog(e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (IllegalStateException e) {
|
||||
showDialog(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
AlivcLivePushInfoListener mPushInfoListener = new AlivcLivePushInfoListener() {
|
||||
@Override
|
||||
public void onPreviewStarted(AlivcLivePusher pusher) {
|
||||
//AlivcLivePusher pusher = mPushController.getLivePusher();
|
||||
// 添加水印
|
||||
for (int i = 0; i < waterMarkInfos.size(); i++) {
|
||||
pusher.addWaterMark(waterMarkInfos.get(i).mWaterMarkPath, waterMarkInfos.get(i).mWaterMarkCoordX, waterMarkInfos.get(i).mWaterMarkCoordY, waterMarkInfos.get(i).mWaterMarkWidth);
|
||||
}
|
||||
ToastUtils.show(getSafeString(R.string.start_preview));
|
||||
sendLogToMessageView("[CBK][INFO] onPreviewStarted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreviewStopped(AlivcLivePusher pusher) {
|
||||
if (isAdded()) {
|
||||
ToastUtils.show(getSafeString(R.string.stop_preview));
|
||||
}
|
||||
sendLogToMessageView("[CBK][INFO] onPreviewStopped");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPushStarted(AlivcLivePusher pusher) {
|
||||
isConnectResult = true;
|
||||
mIsStartAsnycPushing = false;
|
||||
if (isAdded()) {
|
||||
ToastUtils.show(getSafeString(R.string.start_push));
|
||||
}
|
||||
sendLogToMessageView("[CBK][INFO] onPushStarted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFirstFramePushed(AlivcLivePusher pusher) {
|
||||
sendLogToMessageView("[CBK][INFO] onFirstFramePushed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPushPaused(AlivcLivePusher pusher) {
|
||||
ToastUtils.show(getSafeString(R.string.pause_push));
|
||||
sendLogToMessageView("[CBK][INFO] onPushPaused");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPushResumed(AlivcLivePusher pusher) {
|
||||
ToastUtils.show(getSafeString(R.string.resume_push));
|
||||
sendLogToMessageView("[CBK][INFO] onPushResumed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPushStopped(AlivcLivePusher pusher) {
|
||||
ToastUtils.show(getSafeString(R.string.stop_push));
|
||||
sendLogToMessageView("[CBK][INFO] onPushStopped");
|
||||
}
|
||||
|
||||
/**
|
||||
* 推流重启通知
|
||||
*
|
||||
* @param pusher AlivcLivePusher实例
|
||||
*/
|
||||
@Override
|
||||
public void onPushRestarted(AlivcLivePusher pusher) {
|
||||
mIsStartAsnycPushing = false;
|
||||
ToastUtils.show(getSafeString(R.string.restart_success));
|
||||
sendLogToMessageView("[CBK][INFO] onPushRestarted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFirstFramePreviewed(AlivcLivePusher pusher) {
|
||||
sendLogToMessageView("[CBK][INFO] onFirstFramePreviewed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDropFrame(AlivcLivePusher pusher, int countBef, int countAft) {
|
||||
sendLogToMessageView("[CBK][INFO] onDropFrame: [" + countBef + "->" + countAft + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdjustBitrate(AlivcLivePusher pusher, int currentBitrate, int targetBitrate) {
|
||||
sendLogToMessageView("[CBK][INFO] onAdjustBitrate: [" + currentBitrate + "->" + targetBitrate + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdjustFps(AlivcLivePusher pusher, int currentFps, int targetFps) {
|
||||
sendLogToMessageView("[CBK][INFO] onAdjustFps: [" + currentFps + "->" + targetFps + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPushStatistics(AlivcLivePusher pusher, AlivcLivePushStatsInfo statistics) {
|
||||
if (isShowStatistics) {
|
||||
sendLogToMessageView("[CBK][INFO] onPushStatistics: " + statistics);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalRecordEvent(AlivcLiveRecordMediaEvent mediaEvent, String storagePath) {
|
||||
sendLogToMessageView("[CBK][INFO] onLocalRecordEvent: [" + mediaEvent + "][" + storagePath + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteUserEnterRoom(AlivcLivePusher pusher, String userId, boolean isOnline) {
|
||||
sendLogToMessageView("[CBK][INFO] onRemoteUserEnterRoom: [" + userId + "][" + isOnline + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteUserAudioStream(AlivcLivePusher pusher, String userId, boolean isPushing) {
|
||||
sendLogToMessageView("[CBK][INFO] onRemoteUserAudioStream: [" + userId + "][" + isPushing + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteUserVideoStream(AlivcLivePusher pusher, String userId, AlivcLivePlayVideoStreamType videoStreamType, boolean isPushing) {
|
||||
sendLogToMessageView("[CBK][INFO] onRemoteUserVideoStream: [" + userId + "][" + videoStreamType + "][" + isPushing + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetLiveMixTranscodingConfig(AlivcLivePusher pusher, boolean isSuccess, String msg) {
|
||||
sendLogToMessageView("[CBK][INFO] onSetLiveMixTranscodingConfig: [" + isSuccess + "][" + msg + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKickedOutByServer(AlivcLivePusher pusher, AlivcLivePushKickedOutType kickedOutType) {
|
||||
sendLogToMessageView("[CBK][INFO] onKickedOutByServer: [" + kickedOutType + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMicrophoneVolumeUpdate(AlivcLivePusher pusher, int volume) {
|
||||
super.onMicrophoneVolumeUpdate(pusher, volume);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioPublishStateChanged(AlivcLivePublishState oldState, AlivcLivePublishState newState) {
|
||||
sendLogToMessageView("[CBK][INFO] onAudioPublishStateChanged: [" + oldState + "->" + newState + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVideoPublishStateChanged(AlivcLivePublishState oldState, AlivcLivePublishState newState) {
|
||||
sendLogToMessageView("[CBK][INFO] onVideoPublishStateChanged: [" + oldState + "->" + newState + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScreenSharePublishStateChanged(AlivcLivePublishState oldState, AlivcLivePublishState newState) {
|
||||
sendLogToMessageView("[CBK][INFO] onScreenSharePublishStateChanged: [" + oldState + "->" + newState + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalDualAudioStreamPushState(AlivcLivePusher pusher, boolean isPushing) {
|
||||
sendLogToMessageView("[CBK][INFO] onLocalDualAudioStreamPushState: [" + isPushing + "]");
|
||||
}
|
||||
};
|
||||
|
||||
AlivcLivePushErrorListener mPushErrorListener = new AlivcLivePushErrorListener() {
|
||||
@Override
|
||||
public void onSystemError(AlivcLivePusher livePusher, AlivcLivePushError error) {
|
||||
mIsStartAsnycPushing = false;
|
||||
showDialog(getSafeString(R.string.system_error) + error.toString());
|
||||
sendLogToMessageView("[CBK][ERROR] onSystemError: [" + error + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSDKError(AlivcLivePusher livePusher, AlivcLivePushError error) {
|
||||
mIsStartAsnycPushing = false;
|
||||
showDialog(getSafeString(R.string.sdk_error) + error.toString());
|
||||
sendLogToMessageView("[CBK][ERROR] onSDKError: [" + error + "]");
|
||||
}
|
||||
};
|
||||
|
||||
AlivcLivePushNetworkListener mPushNetworkListener = new AlivcLivePushNetworkListener() {
|
||||
@Override
|
||||
public void onNetworkPoor(AlivcLivePusher pusher) {
|
||||
showNetWorkDialog(getSafeString(R.string.network_poor));
|
||||
sendLogToMessageView("[CBK][NETWORK] onNetworkPoor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkRecovery(AlivcLivePusher pusher) {
|
||||
ToastUtils.show(getSafeString(R.string.network_recovery));
|
||||
sendLogToMessageView("[CBK][NETWORK] onNetworkRecovery");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReconnectStart(AlivcLivePusher pusher) {
|
||||
ToastUtils.show(getSafeString(R.string.reconnect_start));
|
||||
sendLogToMessageView("[CBK][NETWORK] onReconnectStart");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReconnectFail(AlivcLivePusher pusher) {
|
||||
mIsStartAsnycPushing = false;
|
||||
showDialog(getSafeString(R.string.reconnect_fail));
|
||||
sendLogToMessageView("[CBK][NETWORK] onReconnectFail");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReconnectSucceed(AlivcLivePusher pusher) {
|
||||
ToastUtils.show(getSafeString(R.string.reconnect_success));
|
||||
sendLogToMessageView("[CBK][NETWORK] onReconnectSucceed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSendDataTimeout(AlivcLivePusher pusher) {
|
||||
mIsStartAsnycPushing = false;
|
||||
showDialog(getSafeString(R.string.senddata_timeout));
|
||||
sendLogToMessageView("[CBK][NETWORK] onSendDataTimeout");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectFail(AlivcLivePusher pusher) {
|
||||
isConnectResult = true;
|
||||
mIsStartAsnycPushing = false;
|
||||
showDialog(getSafeString(R.string.connect_fail));
|
||||
sendLogToMessageView("[CBK][NETWORK] onConnectFail");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkQualityChanged(AlivcLiveNetworkQuality upQuality, AlivcLiveNetworkQuality downQuality) {
|
||||
sendLogToMessageView("[CBK][NETWORK] onNetworkQualityChanged: [" + upQuality + "][" + downQuality + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionLost(AlivcLivePusher pusher) {
|
||||
mIsStartAsnycPushing = false;
|
||||
|
||||
// 断网后停止本地录制
|
||||
AlivcLivePusher livePusher = mPushController.getLivePusher();
|
||||
if (livePusher != null) {
|
||||
livePusher.stopLocalRecord();
|
||||
}
|
||||
|
||||
ToastUtils.show(getSafeString(R.string.connection_lost));
|
||||
sendLogToMessageView("[CBK][NETWORK] onConnectionLost");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onPushURLAuthenticationOverdue(AlivcLivePusher pusher) {
|
||||
sendLogToMessageView("[CBK][NETWORK] onPushURLAuthenticationOverdue:");
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSendMessage(AlivcLivePusher pusher) {
|
||||
sendLogToMessageView("[CBK][NETWORK] onSendMessage: " + getSafeString(R.string.send_message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketsLost(AlivcLivePusher pusher) {
|
||||
ToastUtils.show(getSafeString(R.string.packet_lost));
|
||||
sendLogToMessageView("[CBK][NETWORK] onPacketsLost");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLastMileDetectResultWithQuality(AlivcLivePusher pusher, AlivcLiveNetworkQuality networkQuality) {
|
||||
super.onLastMileDetectResultWithQuality(pusher, networkQuality);
|
||||
sendLogToMessageView("[CBK][NETWORK] onLastMileDetectResultWithQuality: [" + networkQuality + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLastMileDetectResultWithBandWidth(AlivcLivePusher pusher, int code, AlivcLiveNetworkQualityProbeResult networkQualityProbeResult) {
|
||||
super.onLastMileDetectResultWithBandWidth(pusher, code, networkQualityProbeResult);
|
||||
sendLogToMessageView("[CBK][NETWORK] onLastMileDetectResultWithBandWidth: [" + code + "][" + networkQualityProbeResult + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPushURLTokenWillExpire(AlivcLivePusher pusher) {
|
||||
super.onPushURLTokenWillExpire(pusher);
|
||||
sendLogToMessageView("[CBK][NETWORK] onPushURLTokenWillExpire");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPushURLTokenExpired(AlivcLivePusher pusher) {
|
||||
super.onPushURLTokenExpired(pusher);
|
||||
sendLogToMessageView("[CBK][NETWORK] onPushURLTokenExpired");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionStatusChange(AlivcLivePusher pusher, AlivcLiveConnectionStatus connectionStatus, AlivcLiveConnectionStatusChangeReason connectionStatusChangeReason) {
|
||||
super.onConnectionStatusChange(pusher, connectionStatus, connectionStatusChangeReason);
|
||||
sendLogToMessageView("[CBK][NETWORK] onConnectionStatusChange: [" + connectionStatus + "][" + connectionStatusChangeReason + "]");
|
||||
}
|
||||
};
|
||||
|
||||
private AlivcLivePushBGMListener mPushBGMListener = new AlivcLivePushBGMListener() {
|
||||
@Override
|
||||
public void onStarted() {
|
||||
sendLogToMessageView("[CBK][BGM] onStarted");
|
||||
mIsBGMPlaying = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopped() {
|
||||
sendLogToMessageView("[CBK][BGM] onStopped");
|
||||
mIsBGMPlaying = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPaused() {
|
||||
sendLogToMessageView("[CBK][BGM] onPaused");
|
||||
mIsBGMPlaying = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResumed() {
|
||||
sendLogToMessageView("[CBK][BGM] onResumed");
|
||||
mIsBGMPlaying = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(final long progress, final long duration) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mMusicDialog != null) {
|
||||
mMusicDialog.updateProgress(progress, duration);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
sendLogToMessageView("[CBK][BGM] onCompleted");
|
||||
mIsBGMPlaying = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadTimeout() {
|
||||
sendLogToMessageView("[CBK][BGM] onDownloadTimeout");
|
||||
mIsBGMPlaying = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpenFailed() {
|
||||
sendLogToMessageView("[CBK][BGM] onOpenFailed");
|
||||
showDialog(getSafeString(R.string.bgm_open_failed));
|
||||
mIsBGMPlaying = false;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mMusicDialog != null && mMusicDialog.isShowing()) {
|
||||
mMusicDialog.dismiss();
|
||||
mMusicDialog = null;
|
||||
}
|
||||
if (mExecutorService != null && !mExecutorService.isShutdown()) {
|
||||
mExecutorService.shutdown();
|
||||
}
|
||||
destroyBeautyManager();
|
||||
}
|
||||
|
||||
private void showDialog(final String message) {
|
||||
if (getActivity() == null || message == null) {
|
||||
return;
|
||||
}
|
||||
if (mDialog == null || !mDialog.isShowing()) {
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (getActivity() != null) {
|
||||
mDialog = new CommonDialog(getActivity());
|
||||
mDialog.setDialogTitle(getSafeString(R.string.dialog_title));
|
||||
mDialog.setDialogContent(message);
|
||||
mDialog.setConfirmButton(TextFormatUtil.getTextFormat(getActivity(), R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
mDialog.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void showNetWorkDialog(final String message) {
|
||||
if (getActivity() == null || message == null) {
|
||||
return;
|
||||
}
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (getActivity() != null) {
|
||||
final AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
|
||||
dialog.setTitle(getSafeString(R.string.dialog_title));
|
||||
dialog.setMessage(message);
|
||||
dialog.setNegativeButton(getSafeString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
}
|
||||
});
|
||||
dialog.setNeutralButton(getSafeString(R.string.reconnect), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
AlivcLivePusher pusher = mPushController.getLivePusher();
|
||||
try {
|
||||
pusher.reconnectPushAsync(null);
|
||||
} catch (IllegalStateException e) {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private String getMD5(String string) {
|
||||
|
||||
byte[] hash;
|
||||
|
||||
try {
|
||||
hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder hex = new StringBuilder(hash.length * 2);
|
||||
for (byte b : hash) {
|
||||
if ((b & 0xFF) < 0x10) {
|
||||
hex.append("0");
|
||||
}
|
||||
hex.append(Integer.toHexString(b & 0xFF));
|
||||
}
|
||||
|
||||
return hex.toString();
|
||||
}
|
||||
|
||||
private String getUri(String url) {
|
||||
String result = "";
|
||||
String temp = url.substring(7);
|
||||
if (temp != null && !temp.isEmpty()) {
|
||||
result = temp.substring(temp.indexOf("/"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public final String getSafeString(@StringRes int resId) {
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
return getResources().getString(resId);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String getAuthString(String time) {
|
||||
if (!time.isEmpty() && !mPrivacyKey.isEmpty()) {
|
||||
long tempTime = (System.currentTimeMillis() + Integer.valueOf(time)) / 1000;
|
||||
String tempprivacyKey = String.format(mMd5String, getUri(mPushUrl), tempTime, 0, 0, mPrivacyKey);
|
||||
String auth = String.format(mAuthString, tempTime, 0, 0, getMD5(tempprivacyKey));
|
||||
mTempUrl = mPushUrl + auth;
|
||||
} else {
|
||||
mTempUrl = mPushUrl;
|
||||
}
|
||||
return mTempUrl;
|
||||
}
|
||||
|
||||
public boolean isBGMPlaying() {
|
||||
return mIsBGMPlaying;
|
||||
}
|
||||
|
||||
// 初始化美颜
|
||||
private void initBeautyManager() {
|
||||
if (mBeautyManager == null) {
|
||||
Log.d(TAG, "initBeautyManager start");
|
||||
// v4.4.4版本-v6.1.0版本,互动模式下的美颜,处理逻辑参考BeautySDKType.INTERACT_QUEEN,即:InteractQueenBeautyImpl;
|
||||
// v6.1.0以后的版本(从v6.2.0开始),基础模式下的美颜,和互动模式下的美颜,处理逻辑保持一致,即:QueenBeautyImpl;
|
||||
mBeautyManager = BeautyFactory.createBeauty(BeautySDKType.QUEEN, LivePushFragment.this.getActivity());
|
||||
// initialize in texture thread.
|
||||
mBeautyManager.init();
|
||||
mBeautyManager.setBeautyEnable(isBeautyEnable);
|
||||
mBeautyManager.switchCameraId(mCameraId);
|
||||
Log.d(TAG, "initBeautyManager end");
|
||||
}
|
||||
}
|
||||
|
||||
// 销毁美颜
|
||||
private void destroyBeautyManager() {
|
||||
if (mBeautyManager != null) {
|
||||
mBeautyManager.release();
|
||||
mBeautyManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void changeBeautyContainerVisibility() {
|
||||
if (mBeautyBeautyContainerView.getVisibility() == View.VISIBLE) {
|
||||
mActionBar.setVisibility(View.VISIBLE);
|
||||
mQueenMenuPanel.onHideMenu();
|
||||
mBeautyBeautyContainerView.setVisibility(View.GONE);
|
||||
} else {
|
||||
mActionBar.setVisibility(View.GONE);
|
||||
mQueenMenuPanel.onShowMenu();
|
||||
mBeautyBeautyContainerView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void changeSoundEffectVisibility() {
|
||||
if (mSoundEffectView.getVisibility() == View.VISIBLE) {
|
||||
mActionBar.setVisibility(View.VISIBLE);
|
||||
mSoundEffectView.setVisibility(View.GONE);
|
||||
} else {
|
||||
mActionBar.setVisibility(View.GONE);
|
||||
mSoundEffectView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateOperaButtonState(boolean value) {
|
||||
if (mOperaButton != null) {
|
||||
mOperaButton.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mOperaButton != null) {
|
||||
mOperaButton.setText(value ? getSafeString(R.string.pause_button) : getSafeString(R.string.resume_button));
|
||||
mOperaButton.setSelected(!value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (mPreviewButton != null) {
|
||||
mPreviewButton.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mPreviewButton != null) {
|
||||
mPreviewButton.setText(value ? getSafeString(R.string.stop_preview_button) : getSafeString(R.string.start_preview_button));
|
||||
mPreviewButton.setSelected(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 发送日志到消息视图
|
||||
private void sendLogToMessageView(String message) {
|
||||
if (mMessagesView != null) {
|
||||
mMessagesView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mMessagesView != null) {
|
||||
mMessagesView.appendMessage(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.alivc.live.baselive_push.ui;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
|
||||
import com.alivc.live.commonbiz.LocalStreamReader;
|
||||
import com.alivc.live.commonbiz.ResourcesConst;
|
||||
import com.alivc.live.pusher.AlivcLivePushConfig;
|
||||
import com.alivc.live.pusher.AlivcLivePusher;
|
||||
import com.alivc.live.pusher.AlivcResolutionEnum;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class LivePushViewModel extends AndroidViewModel {
|
||||
|
||||
private final Context mApplicationContext;
|
||||
private LocalStreamReader mLocalStreamReader;
|
||||
|
||||
public LivePushViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
mApplicationContext = application;
|
||||
}
|
||||
|
||||
public void initReadFile(AlivcLivePushConfig config) {
|
||||
AlivcResolutionEnum resolution = config.getResolution();
|
||||
int width = AlivcResolutionEnum.getResolutionWidth(resolution, config.getLivePushMode());
|
||||
int height = AlivcResolutionEnum.getResolutionHeight(resolution, config.getLivePushMode());
|
||||
mLocalStreamReader = new LocalStreamReader.Builder()
|
||||
.setVideoWith(width)
|
||||
.setVideoHeight(height)
|
||||
.setVideoStride(width)
|
||||
.setVideoSize(height * width * 3 / 2)
|
||||
.setVideoRotation(0)
|
||||
.setAudioSampleRate(44100)
|
||||
.setAudioChannel(1)
|
||||
.setAudioBufferSize(2048)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void startYUV(final Context context, AlivcLivePusher mAlivcLivePusher) {
|
||||
File f = ResourcesConst.localCaptureYUVFilePath(context);
|
||||
mLocalStreamReader.readYUVData(f, (buffer, pts, videoWidth, videoHeight, videoStride, videoSize, videoRotation) -> {
|
||||
mAlivcLivePusher.inputStreamVideoData(buffer, videoWidth, videoHeight, videoStride, videoSize, pts, videoRotation);
|
||||
});
|
||||
}
|
||||
|
||||
public void stopYUV() {
|
||||
mLocalStreamReader.stopYUV();
|
||||
}
|
||||
|
||||
public void stopPcm() {
|
||||
mLocalStreamReader.stopPcm();
|
||||
}
|
||||
|
||||
private void startPCM(final Context context, AlivcLivePusher mAlivcLivePusher) {
|
||||
File f = ResourcesConst.localCapturePCMFilePath(context);
|
||||
mLocalStreamReader.readPCMData(f, (buffer, length, pts, audioSampleRate, audioChannel) -> {
|
||||
mAlivcLivePusher.inputStreamAudioData(buffer, length, audioSampleRate, audioChannel, pts);
|
||||
});
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(boolean mAsync, SurfaceView mPreviewView, AlivcLivePusher mAlivcLivePusher) {
|
||||
if (mAlivcLivePusher != null) {
|
||||
if (mAsync) {
|
||||
mAlivcLivePusher.startPreviewAsync(mPreviewView);
|
||||
} else {
|
||||
mAlivcLivePusher.startPreview(mPreviewView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startYUV(AlivcLivePusher mAlivcLivePusher) {
|
||||
startYUV(mApplicationContext, mAlivcLivePusher);
|
||||
}
|
||||
|
||||
public void startPCM(AlivcLivePusher mAlivcLivePusher) {
|
||||
startPCM(mApplicationContext, mAlivcLivePusher);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,714 @@
|
||||
|
||||
package com.alivc.live.baselive_push.ui;
|
||||
|
||||
import static com.alivc.live.pusher.AlivcLivePushConstants.DEFAULT_VALUE_AUTO_FOCUS;
|
||||
import static com.alivc.live.pusher.AlivcLivePushConstants.DEFAULT_VALUE_PREVIEW_MIRROR;
|
||||
import static com.alivc.live.pusher.AlivcLivePushConstants.DEFAULT_VALUE_PUSH_MIRROR;
|
||||
import static com.alivc.live.pusher.AlivcPreviewOrientationEnum.ORIENTATION_PORTRAIT;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.DownloadManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.Camera;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.acker.simplezxing.activity.CaptureActivity;
|
||||
import com.alivc.live.annotations.AlivcLiveMode;
|
||||
import com.alivc.live.baselive_push.R;
|
||||
import com.alivc.live.baselive_push.bean.GsonUtils;
|
||||
import com.alivc.live.commonbiz.ResourcesDownload;
|
||||
import com.alivc.live.commonbiz.SharedPreferenceUtils;
|
||||
import com.alivc.live.commonbiz.backdoor.BackDoorActivity;
|
||||
import com.alivc.live.commonbiz.backdoor.BackDoorInstance;
|
||||
import com.alivc.live.commonbiz.test.PushDemoTestConstants;
|
||||
import com.alivc.live.commonui.configview.LivePushSettingView;
|
||||
import com.alivc.live.commonui.utils.StatusBarUtil;
|
||||
import com.alivc.live.commonui.widgets.AVLiveLoadingDialog;
|
||||
import com.alivc.live.commonui.widgets.PushWaterMarkDialog;
|
||||
import com.alivc.live.commonutils.DownloadUtil;
|
||||
import com.alivc.live.commonutils.FastClickUtil;
|
||||
import com.alivc.live.commonutils.FileUtil;
|
||||
import com.alivc.live.commonutils.LogcatHelper;
|
||||
import com.alivc.live.commonutils.ToastUtils;
|
||||
import com.alivc.live.pusher.AlivcAudioChannelEnum;
|
||||
import com.alivc.live.pusher.AlivcAudioSampleRateEnum;
|
||||
import com.alivc.live.pusher.AlivcAudioSceneModeEnum;
|
||||
import com.alivc.live.pusher.AlivcEncodeModeEnum;
|
||||
import com.alivc.live.pusher.AlivcImageFormat;
|
||||
import com.alivc.live.pusher.AlivcLiveBase;
|
||||
import com.alivc.live.pusher.AlivcLivePushCameraTypeEnum;
|
||||
import com.alivc.live.pusher.AlivcLivePushConfig;
|
||||
import com.alivc.live.pusher.AlivcLivePushConstants;
|
||||
import com.alivc.live.pusher.AlivcPreviewDisplayMode;
|
||||
import com.alivc.live.pusher.AlivcPreviewOrientationEnum;
|
||||
import com.alivc.live.pusher.AlivcResolutionEnum;
|
||||
import com.alivc.live.pusher.AlivcSoundFormat;
|
||||
import com.alivc.live.pusher.WaterMarkInfo;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PushConfigActivity extends AppCompatActivity {
|
||||
|
||||
private RelativeLayout mInteractionRelativeLayout;
|
||||
private RadioGroup mLivePushModeRadioGroup;
|
||||
private LivePushSettingView mLivePushSettingView;
|
||||
private AlivcResolutionEnum mCurrentResolution = AlivcResolutionEnum.RESOLUTION_540P;
|
||||
|
||||
private AlivcResolutionEnum mDefinition = AlivcResolutionEnum.RESOLUTION_540P;
|
||||
private static final int REQ_CODE_PERMISSION = 0x1111;
|
||||
private InputMethodManager manager;
|
||||
|
||||
private View mPublish;
|
||||
private TextView mLocalLogTv;
|
||||
private EditText mUrl;
|
||||
private ImageView mQr;
|
||||
private ImageView mBack;
|
||||
|
||||
private AlivcLivePushConfig mAlivcLivePushConfig;
|
||||
private boolean mAsyncValue = true;
|
||||
private boolean mAudioOnlyPush = false;
|
||||
private boolean mVideoOnlyPush = false;
|
||||
private AlivcPreviewOrientationEnum mOrientationEnum = ORIENTATION_PORTRAIT;
|
||||
private ArrayList<WaterMarkInfo> mWaterMarkInfos = new ArrayList<>();
|
||||
|
||||
private int mCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
|
||||
private boolean isFlash = false;
|
||||
|
||||
private String mAuthTimeStr = "";
|
||||
private String mPrivacyKeyStr = "";
|
||||
private boolean mMixStream = false;
|
||||
|
||||
private View mTabArgsLayout;
|
||||
private View mTabActionLayout;
|
||||
private View mTabArgsView;
|
||||
private View mTabActionView;
|
||||
private int mFpsConfig = 25;//默认帧率
|
||||
|
||||
@Nullable
|
||||
private AVLiveLoadingDialog mLoadingDialog;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
StatusBarUtil.translucent(this, getColor(R.color.main_color));
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
setContentView(R.layout.push_setting);
|
||||
|
||||
mAlivcLivePushConfig = new AlivcLivePushConfig();
|
||||
|
||||
//设置音乐模式
|
||||
//mAlivcLivePushConfig.setAudioSceneMode(AlivcAudioSceneModeEnum.AUDIO_SCENE_MUSIC_MODE);
|
||||
// 设置编码器类型
|
||||
// mAlivcLivePushConfig.setVideoEncodeType(Encode_TYPE_H265);
|
||||
// 设置b帧个数
|
||||
// mAlivcLivePushConfig.setBFrames(1);
|
||||
|
||||
if (mAlivcLivePushConfig.getPreviewOrientation() == AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_RIGHT.getOrientation() || mAlivcLivePushConfig.getPreviewOrientation() == AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_LEFT.getOrientation()) {
|
||||
mAlivcLivePushConfig.setNetworkPoorPushImage(getFilesDir().getPath() + File.separator + "alivc_resource/poor_network_land.png");
|
||||
mAlivcLivePushConfig.setPausePushImage(getFilesDir().getPath() + File.separator + "alivc_resource/background_push_land.png");
|
||||
} else {
|
||||
mAlivcLivePushConfig.setNetworkPoorPushImage(getFilesDir().getPath() + File.separator + "alivc_resource/poor_network.png");
|
||||
mAlivcLivePushConfig.setPausePushImage(getFilesDir().getPath() + File.separator + "alivc_resource/background_push.png");
|
||||
}
|
||||
mAlivcLivePushConfig.setMediaProjectionPermissionResultData(null);
|
||||
initView();
|
||||
setClick();
|
||||
addWaterMarkInfo();
|
||||
if (mAlivcLivePushConfig != null) {
|
||||
mAlivcLivePushConfig.setPreviewDisplayMode(AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FILL);
|
||||
SharedPreferenceUtils.setDisplayFit(getApplicationContext(), AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FILL
|
||||
|
||||
.getPreviewDisplayMode());
|
||||
}
|
||||
Intent intent = getIntent();
|
||||
String url = intent.getStringExtra("pushUrl");
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
mUrl.setText(url);
|
||||
}
|
||||
|
||||
// Demo逻辑,用于测试,请勿follow!如果强制RTC预发环境,那么增加extra配置
|
||||
// if (BackDoorInstance.getInstance().isForceRTCPreEnvironment()) {
|
||||
// HashMap<String, String> extras = new HashMap<>(4);
|
||||
// extras.put("user_specified_environment", "PRE_RELEASE");
|
||||
// mAlivcLivePushConfig.setExtras(extras);
|
||||
// }
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mUrl = (EditText) findViewById(R.id.url_editor);
|
||||
mPublish = findViewById(R.id.beginPublish);
|
||||
mQr = (ImageView) findViewById(R.id.qr_code);
|
||||
mBack = (ImageView) findViewById(R.id.iv_back);
|
||||
|
||||
SharedPreferenceUtils.setHintTargetBit(getApplicationContext(), AlivcLivePushConstants.BITRATE_540P_RESOLUTION_FIRST.DEFAULT_VALUE_INT_TARGET_BITRATE.getBitrate());
|
||||
SharedPreferenceUtils.setHintMinBit(getApplicationContext(), AlivcLivePushConstants.BITRATE_540P_RESOLUTION_FIRST.DEFAULT_VALUE_INT_MIN_BITRATE.getBitrate());
|
||||
|
||||
mTabArgsLayout = findViewById(R.id.tab_args_layout);
|
||||
// 测试用,长按推流参数四个字,自动填写rtmp://
|
||||
mTabArgsLayout.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
String filledUrl = mUrl.getText().toString();
|
||||
if (TextUtils.isEmpty(filledUrl) || !(filledUrl.startsWith("rtmp://") || filledUrl.startsWith("artc://"))) {
|
||||
mUrl.setText("rtmp://");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
mTabActionLayout = findViewById(R.id.tab_action_layout);
|
||||
mTabArgsView = (View) findViewById(R.id.tab_args_view);
|
||||
mTabActionView = (View) findViewById(R.id.tab_action_view);
|
||||
mLocalLogTv = findViewById(R.id.local_log);
|
||||
// mVideoEncoder.check(R.id.h264_encoder);
|
||||
// mBFrames.check(R.id.b_frame_no);
|
||||
mInteractionRelativeLayout = findViewById(R.id.rl_interaction);
|
||||
mLivePushModeRadioGroup = findViewById(R.id.live_push_mode);
|
||||
mLivePushSettingView = findViewById(R.id.push_setting_view);
|
||||
|
||||
mInteractionRelativeLayout.setVisibility(AlivcLiveBase.isSupportLiveMode(AlivcLiveMode.AlivcLiveInteractiveMode) ? View.VISIBLE : View.GONE);
|
||||
|
||||
String initUrl = PushDemoTestConstants.getTestPushUrl();
|
||||
if (!initUrl.isEmpty()) {
|
||||
mUrl.setText(initUrl);
|
||||
}
|
||||
|
||||
mLivePushSettingView.showArgsContent(true);
|
||||
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
toLive();
|
||||
}
|
||||
},3000);
|
||||
}
|
||||
|
||||
private void setClick() {
|
||||
mLivePushSettingView.bitrateControl.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setEnableBitrateControl(isChecked);
|
||||
});
|
||||
mLivePushSettingView.targetVideoBitrate.observe(this, bitrate -> {
|
||||
SharedPreferenceUtils.setHintTargetBit(getApplicationContext(), bitrate);
|
||||
mAlivcLivePushConfig.setTargetVideoBitrate(bitrate);
|
||||
});
|
||||
mLivePushSettingView.minVideoBitrate.observe(this, bitrate -> {
|
||||
SharedPreferenceUtils.setHintMinBit(getApplicationContext(), bitrate);
|
||||
mAlivcLivePushConfig.setMinVideoBitrate(bitrate);
|
||||
});
|
||||
mLivePushSettingView.initialVideoBitrate.observe(this, bitrate -> {
|
||||
SharedPreferenceUtils.setHintMinBit(getApplicationContext(), bitrate);
|
||||
mAlivcLivePushConfig.setInitialVideoBitrate(bitrate);
|
||||
});
|
||||
mLivePushSettingView.audioBitrate.observe(this, bitrate -> {
|
||||
SharedPreferenceUtils.setHintMinBit(getApplicationContext(), bitrate);
|
||||
mAlivcLivePushConfig.setAudioBitRate(bitrate);
|
||||
});
|
||||
mLivePushSettingView.variableResolution.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setEnableAutoResolution(isChecked);
|
||||
});
|
||||
mLivePushSettingView.minFps.observe(this, minFps -> {
|
||||
mAlivcLivePushConfig.setMinFps(minFps);
|
||||
});
|
||||
mLivePushSettingView.audioSampleRate.observe(this, sampleRate -> {
|
||||
mAlivcLivePushConfig.setAudioSampleRate(sampleRate);
|
||||
});
|
||||
mLivePushSettingView.gop.observe(this, gop -> {
|
||||
mAlivcLivePushConfig.setVideoEncodeGop(gop);
|
||||
});
|
||||
mLivePushSettingView.fps.observe(this, fps -> {
|
||||
mFpsConfig = fps.getFps();
|
||||
mAlivcLivePushConfig.setFps(fps);
|
||||
});
|
||||
mLivePushSettingView.videoHardwareDecode.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setVideoEncodeMode(isChecked ? AlivcEncodeModeEnum.Encode_MODE_HARD : AlivcEncodeModeEnum.Encode_MODE_SOFT);
|
||||
});
|
||||
mLivePushSettingView.audioHardwareDecode.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setAudioEncodeMode(isChecked ? AlivcEncodeModeEnum.Encode_MODE_HARD : AlivcEncodeModeEnum.Encode_MODE_SOFT);
|
||||
});
|
||||
mLivePushSettingView.pushMirror.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setPushMirror(isChecked);
|
||||
SharedPreferenceUtils.setPushMirror(getApplicationContext(), isChecked);
|
||||
});
|
||||
mLivePushSettingView.previewMirror.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setPreviewMirror(isChecked);
|
||||
SharedPreferenceUtils.setPreviewMirror(getApplicationContext(), isChecked);
|
||||
});
|
||||
mLivePushSettingView.enableFrontCamera.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setCameraType(isChecked ? AlivcLivePushCameraTypeEnum.CAMERA_TYPE_FRONT : AlivcLivePushCameraTypeEnum.CAMERA_TYPE_BACK);
|
||||
mCameraId = (isChecked ? AlivcLivePushCameraTypeEnum.CAMERA_TYPE_FRONT.getCameraId() : AlivcLivePushCameraTypeEnum.CAMERA_TYPE_BACK.getCameraId());
|
||||
});
|
||||
mLivePushSettingView.resolution.observe(this, resolution -> {
|
||||
mCurrentResolution = resolution;
|
||||
});
|
||||
mLivePushSettingView.autoFocus.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setAutoFocus(isChecked);
|
||||
SharedPreferenceUtils.setAutofocus(getApplicationContext(), isChecked);
|
||||
});
|
||||
mLivePushSettingView.enableBeauty.observe(this, isChecked -> {
|
||||
SharedPreferenceUtils.setBeautyOn(getApplicationContext(), isChecked);
|
||||
});
|
||||
mLivePushSettingView.videoOnly.observe(this, isChecked -> {
|
||||
mVideoOnlyPush = isChecked;
|
||||
mAlivcLivePushConfig.setVideoOnly(mVideoOnlyPush);
|
||||
});
|
||||
mLivePushSettingView.audioOnly.observe(this, isChecked -> {
|
||||
mAudioOnlyPush = isChecked;
|
||||
mAlivcLivePushConfig.setAudioOnly(mAudioOnlyPush);
|
||||
});
|
||||
mLivePushSettingView.pauseImage.observe(this, isChecked -> {
|
||||
if (!isChecked) {
|
||||
mAlivcLivePushConfig.setPausePushImage("");
|
||||
} else {
|
||||
if (mAlivcLivePushConfig.getPreviewOrientation() == AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_LEFT.getOrientation() || mAlivcLivePushConfig.getPreviewOrientation() == AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_RIGHT.getOrientation()) {
|
||||
mAlivcLivePushConfig.setPausePushImage(getFilesDir().getPath() + File.separator + "alivc_resource/background_push_land.png");
|
||||
} else {
|
||||
mAlivcLivePushConfig.setPausePushImage(getFilesDir().getPath() + File.separator + "alivc_resource/background_push.png");
|
||||
}
|
||||
}
|
||||
});
|
||||
mLivePushSettingView.netWorkImage.observe(this, isChecked -> {
|
||||
if (!isChecked) {
|
||||
mAlivcLivePushConfig.setNetworkPoorPushImage("");
|
||||
} else {
|
||||
if (mAlivcLivePushConfig.getPreviewOrientation() == AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_LEFT.getOrientation() || mAlivcLivePushConfig.getPreviewOrientation() == AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_RIGHT.getOrientation()) {
|
||||
mAlivcLivePushConfig.setNetworkPoorPushImage(getFilesDir().getPath() + File.separator + "alivc_resource/poor_network_land.png");
|
||||
} else {
|
||||
mAlivcLivePushConfig.setNetworkPoorPushImage(getFilesDir().getPath() + File.separator + "alivc_resource/poor_network.png");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mLivePushSettingView.async.observe(this, isChecked -> {
|
||||
mAsyncValue = isChecked;
|
||||
});
|
||||
mLivePushSettingView.musicMode.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setAudioSceneMode(isChecked ? AlivcAudioSceneModeEnum.AUDIO_SCENE_MUSIC_MODE : AlivcAudioSceneModeEnum.AUDIO_SCENE_DEFAULT_MODE);
|
||||
});
|
||||
mLivePushSettingView.extern.observe(this, isChecked -> {
|
||||
mAlivcLivePushConfig.setExternMainStream(isChecked, AlivcImageFormat.IMAGE_FORMAT_YUVNV12, AlivcSoundFormat.SOUND_FORMAT_S16);
|
||||
mAlivcLivePushConfig.setAudioChannels(AlivcAudioChannelEnum.AUDIO_CHANNEL_ONE);
|
||||
mAlivcLivePushConfig.setAudioSampleRate(AlivcAudioSampleRateEnum.AUDIO_SAMPLE_RATE_44100);
|
||||
if (isChecked) {
|
||||
startDownloadYUV();
|
||||
}
|
||||
});
|
||||
mLivePushSettingView.localLog.observe(this, isChecked -> {
|
||||
if (isChecked) {
|
||||
LogcatHelper.getInstance(getApplicationContext()).start();
|
||||
} else {
|
||||
LogcatHelper.getInstance(getApplicationContext()).stop();
|
||||
}
|
||||
});
|
||||
|
||||
mLivePushSettingView.previewDisplayMode.observe(this, previewDisplayMode -> {
|
||||
mAlivcLivePushConfig.setPreviewDisplayMode(previewDisplayMode);
|
||||
SharedPreferenceUtils.setDisplayFit(getApplicationContext(), previewDisplayMode.getPreviewDisplayMode());
|
||||
});
|
||||
|
||||
mLivePushSettingView.cameraCaptureOutputPreference.observe(this, preference -> {
|
||||
mAlivcLivePushConfig.setCameraCaptureOutputPreference(preference);
|
||||
});
|
||||
|
||||
mLivePushSettingView.audioChannel.observe(this, audioChannel -> {
|
||||
mAlivcLivePushConfig.setAudioChannels(audioChannel);
|
||||
});
|
||||
|
||||
mLivePushSettingView.audioProfile.observe(this, audioProfile -> {
|
||||
mAlivcLivePushConfig.setAudioProfile(audioProfile);
|
||||
});
|
||||
|
||||
mLivePushSettingView.videoEncodeType.observe(this, videoEncodeType -> {
|
||||
mAlivcLivePushConfig.setVideoEncodeType(videoEncodeType);
|
||||
});
|
||||
|
||||
mLivePushSettingView.bFrame.observe(this, bFrame -> {
|
||||
mAlivcLivePushConfig.setBFrames(bFrame);
|
||||
});
|
||||
|
||||
mLivePushSettingView.previewOrientation.observe(this, orientation -> {
|
||||
mAlivcLivePushConfig.setPreviewOrientation(orientation);
|
||||
mOrientationEnum = orientation;
|
||||
});
|
||||
|
||||
mLivePushSettingView.pauseImagePath.observe(this, path -> {
|
||||
if (mAlivcLivePushConfig.getPausePushImage() == null || mAlivcLivePushConfig.getPausePushImage().equals("")) {
|
||||
mAlivcLivePushConfig.setPausePushImage(path);
|
||||
}
|
||||
});
|
||||
|
||||
mLivePushSettingView.netWorkImagePath.observe(this, path -> {
|
||||
if (mAlivcLivePushConfig.getNetworkPoorPushImage() != null && !mAlivcLivePushConfig.getNetworkPoorPushImage().equals("")) {
|
||||
mAlivcLivePushConfig.setNetworkPoorPushImage(path);
|
||||
}
|
||||
});
|
||||
|
||||
mLivePushSettingView.qualityMode.observe(this, quality -> {
|
||||
mAlivcLivePushConfig.setQualityMode(quality);
|
||||
});
|
||||
|
||||
mLivePushSettingView.showWaterMark.observe(this, isShown -> {
|
||||
if (isShown) {
|
||||
PushWaterMarkDialog pushWaterMarkDialog = new PushWaterMarkDialog();
|
||||
pushWaterMarkDialog.setWaterMarkInfo(mWaterMarkInfos);
|
||||
pushWaterMarkDialog.show(getSupportFragmentManager(), "waterDialog");
|
||||
}
|
||||
});
|
||||
|
||||
mPublish.setOnClickListener(onClickListener);
|
||||
mTabArgsLayout.setOnClickListener(onClickListener);
|
||||
mTabActionLayout.setOnClickListener(onClickListener);
|
||||
mQr.setOnClickListener(onClickListener);
|
||||
mBack.setOnClickListener(onClickListener);
|
||||
mLocalLogTv.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
jump2BackdoorActivity();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
mLivePushModeRadioGroup.setOnCheckedChangeListener((radioGroup, i) -> {
|
||||
if (i == R.id.push_mode_interaction) {
|
||||
//互动模式
|
||||
mAlivcLivePushConfig.setEnableRTSForInteractiveMode(false);
|
||||
mAlivcLivePushConfig.setLivePushMode(AlivcLiveMode.AlivcLiveInteractiveMode);
|
||||
} else if (i == R.id.push_mode_raw_stream) {
|
||||
//推拉裸流
|
||||
mAlivcLivePushConfig.setEnableRTSForInteractiveMode(true);
|
||||
mAlivcLivePushConfig.setLivePushMode(AlivcLiveMode.AlivcLiveInteractiveMode);
|
||||
} else {
|
||||
//标准模式
|
||||
mAlivcLivePushConfig.setEnableRTSForInteractiveMode(false);
|
||||
mAlivcLivePushConfig.setLivePushMode(AlivcLiveMode.AlivcLiveBasicMode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private View.OnClickListener onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
int id = view.getId();
|
||||
if (id == R.id.beginPublish) {
|
||||
toLive();
|
||||
|
||||
} else if (id == R.id.qr_code) {
|
||||
if (ContextCompat.checkSelfPermission(PushConfigActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
||||
// Do not have the permission of camera, request it.
|
||||
ActivityCompat.requestPermissions(PushConfigActivity.this, new String[]{Manifest.permission.CAMERA}, REQ_CODE_PERMISSION);
|
||||
} else {
|
||||
// Have gotten the permission
|
||||
startCaptureActivityForResult();
|
||||
}
|
||||
} else if (id == R.id.iv_back) {
|
||||
finish();
|
||||
} else if (id == R.id.tab_args_layout) {
|
||||
mTabArgsView.setVisibility(View.VISIBLE);
|
||||
mTabActionView.setVisibility(View.INVISIBLE);
|
||||
mLivePushSettingView.showArgsContent(true);
|
||||
mInteractionRelativeLayout.setVisibility(AlivcLiveBase.isSupportLiveMode(AlivcLiveMode.AlivcLiveInteractiveMode) ? View.VISIBLE : View.GONE);
|
||||
} else if (id == R.id.tab_action_layout) {
|
||||
mTabActionView.setVisibility(View.VISIBLE);
|
||||
mTabArgsView.setVisibility(View.INVISIBLE);
|
||||
mLivePushSettingView.showArgsContent(false);
|
||||
mInteractionRelativeLayout.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void toLive() {
|
||||
if (FastClickUtil.isProcessing()) {
|
||||
return;
|
||||
}
|
||||
if (getPushConfig() != null) {
|
||||
|
||||
ArrayList<WaterMarkInfo> waterMarkInfos = new ArrayList<>();
|
||||
if (mLivePushSettingView.enableWaterMark()) {
|
||||
waterMarkInfos.addAll(mWaterMarkInfos);
|
||||
}
|
||||
if (mCurrentResolution == AlivcResolutionEnum.RESOLUTION_SELF_DEFINE) {
|
||||
AlivcResolutionEnum.RESOLUTION_SELF_DEFINE.setSelfDefineResolution(mLivePushSettingView.getSelfDefineResolutionWidth(), mLivePushSettingView.getSelfDefineResolutionHeight());
|
||||
mAlivcLivePushConfig.setResolution(AlivcResolutionEnum.RESOLUTION_SELF_DEFINE);
|
||||
Log.i("LIVE","LIVECONFIGRESOLUTION_SELF_DEFINE1:"+ mLivePushSettingView.getSelfDefineResolutionWidth());
|
||||
Log.i("LIVE","LIVECONFIGRESOLUTION_SELF_DEFINE2:"+ mLivePushSettingView.getSelfDefineResolutionHeight());
|
||||
|
||||
} else {
|
||||
mAlivcLivePushConfig.setResolution(mCurrentResolution);
|
||||
Log.i("LIVE","LIVECONFIGRESOLUTION_SELF_DEFINE3:"+ mCurrentResolution);
|
||||
|
||||
}
|
||||
|
||||
if (mUrl.getText().toString().contains("rtmp://") || mUrl.getText().toString().contains("artc://")) {
|
||||
checkModelAndRun(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LivePushActivity.startActivity(PushConfigActivity.this, mAlivcLivePushConfig, mUrl.getText().toString(),
|
||||
mAsyncValue, mAudioOnlyPush, mVideoOnlyPush, mOrientationEnum, mCameraId, isFlash, mAuthTimeStr,
|
||||
mPrivacyKeyStr, mMixStream, mAlivcLivePushConfig.isExternMainStream(), mLivePushSettingView.enableBeauty(), mFpsConfig,
|
||||
waterMarkInfos);
|
||||
|
||||
Log.i("LIVE","LIVECONFIGmAlivcLivePushConfig:"+ GsonUtils.beanToJSONString(mAlivcLivePushConfig));
|
||||
Log.i("LIVE","LIVECONFIGmUrl:"+ mUrl.getText().toString());
|
||||
Log.i("LIVE","LIVECONFIGmAsyncValue:"+ mAsyncValue);
|
||||
Log.i("LIVE","LIVECONFIGmAudioOnlyPush:"+mAudioOnlyPush );
|
||||
Log.i("LIVE","LIVECONFIGmVideoOnlyPush:"+ mVideoOnlyPush);
|
||||
Log.i("LIVE","LIVECONFIGmOrientationEnum:"+mOrientationEnum );
|
||||
Log.i("LIVE","LIVECONFIGmCameraId:"+ mCameraId);
|
||||
Log.i("LIVE","LIVECONFIGisFlash:"+ isFlash);
|
||||
Log.i("LIVE","LIVECONFIGmAuthTimeStr:"+ mAuthTimeStr);
|
||||
Log.i("LIVE","LIVECONFIGmPrivacyKeyStr:"+ mPrivacyKeyStr);
|
||||
Log.i("LIVE","LIVECONFIGmMixStream:"+mMixStream );
|
||||
Log.i("LIVE","LIVECONFIGmAlivcLivePushConfig:"+ mAlivcLivePushConfig.isExternMainStream());
|
||||
Log.i("LIVE","LIVECONFIGenableBeauty:"+ mLivePushSettingView.enableBeauty());
|
||||
Log.i("LIVE","LIVECONFIGmFpsConfig:"+mFpsConfig );
|
||||
Log.i("LIVE","LIVECONFIGwaterMarkInfos:"+GsonUtils.beanToJSONString(waterMarkInfos) );
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ToastUtils.show("url format unsupported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mLivePushSettingView.setPushMirror(SharedPreferenceUtils.isPushMirror(getApplicationContext(), DEFAULT_VALUE_PUSH_MIRROR));
|
||||
mLivePushSettingView.setPreviewMirror(SharedPreferenceUtils.isPreviewMirror(getApplicationContext(), DEFAULT_VALUE_PREVIEW_MIRROR));
|
||||
mLivePushSettingView.setAutoFocus(SharedPreferenceUtils.isAutoFocus(getApplicationContext(), DEFAULT_VALUE_AUTO_FOCUS));
|
||||
mLivePushSettingView.setBeautyOn(SharedPreferenceUtils.isBeautyOn(getApplicationContext()));
|
||||
}
|
||||
|
||||
private void startCaptureActivityForResult() {
|
||||
Intent intent = new Intent(PushConfigActivity.this, CaptureActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(CaptureActivity.KEY_NEED_BEEP, CaptureActivity.VALUE_BEEP);
|
||||
bundle.putBoolean(CaptureActivity.KEY_NEED_VIBRATION, CaptureActivity.VALUE_VIBRATION);
|
||||
bundle.putBoolean(CaptureActivity.KEY_NEED_EXPOSURE, CaptureActivity.VALUE_NO_EXPOSURE);
|
||||
bundle.putByte(CaptureActivity.KEY_FLASHLIGHT_MODE, CaptureActivity.VALUE_FLASHLIGHT_OFF);
|
||||
bundle.putByte(CaptureActivity.KEY_ORIENTATION_MODE, CaptureActivity.VALUE_ORIENTATION_AUTO);
|
||||
bundle.putBoolean(CaptureActivity.KEY_SCAN_AREA_FULL_SCREEN, CaptureActivity.VALUE_SCAN_AREA_FULL_SCREEN);
|
||||
bundle.putBoolean(CaptureActivity.KEY_NEED_SCAN_HINT_TEXT, CaptureActivity.VALUE_SCAN_HINT_TEXT);
|
||||
intent.putExtra(CaptureActivity.EXTRA_SETTING_BUNDLE, bundle);
|
||||
startActivityForResult(intent, CaptureActivity.REQ_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
switch (requestCode) {
|
||||
case REQ_CODE_PERMISSION: {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
// User agree the permission
|
||||
startCaptureActivityForResult();
|
||||
} else {
|
||||
// User disagree the permission
|
||||
ToastUtils.show("You must agree the camera permission request before you use the code scan function");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private AlivcLivePushConfig getPushConfig() {
|
||||
if (mUrl.getText().toString().isEmpty()) {
|
||||
ToastUtils.show(getString(R.string.url_empty));
|
||||
return null;
|
||||
}
|
||||
mAlivcLivePushConfig.setResolution(mDefinition);
|
||||
mAlivcLivePushConfig.setInitialVideoBitrate(Integer.parseInt(mLivePushSettingView.getInitVideoBitrate()));
|
||||
mAlivcLivePushConfig.setAudioBitRate(1000 * Integer.parseInt(mLivePushSettingView.getAudioBitrate()));
|
||||
|
||||
mAlivcLivePushConfig.setMinVideoBitrate(Integer.parseInt(mLivePushSettingView.getMinVideoBitrate()));
|
||||
SharedPreferenceUtils.setMinBit(getApplicationContext(), Integer.parseInt(mLivePushSettingView.getMinVideoBitrate()));
|
||||
|
||||
mAlivcLivePushConfig.setTargetVideoBitrate(Integer.parseInt(mLivePushSettingView.getTargetVideoBitrate()));
|
||||
SharedPreferenceUtils.setTargetBit(getApplicationContext(), Integer.parseInt(mLivePushSettingView.getTargetVideoBitrate()));
|
||||
|
||||
mAlivcLivePushConfig.setConnectRetryCount(mLivePushSettingView.getRetryCount());
|
||||
mAlivcLivePushConfig.setConnectRetryInterval(mLivePushSettingView.getRetryInterval());
|
||||
|
||||
mAuthTimeStr = mLivePushSettingView.getAuthTime();
|
||||
mPrivacyKeyStr = mLivePushSettingView.getPrivacyKey();
|
||||
Uri uri = Uri.parse(mUrl.getText().toString().trim());
|
||||
String keys = uri.getQueryParameter("auth_key");
|
||||
mPrivacyKeyStr =keys;
|
||||
Log.i("BIKAOVIDEO","BIKAOVIDEO:"+mPrivacyKeyStr);
|
||||
return mAlivcLivePushConfig;
|
||||
}
|
||||
|
||||
private void addWaterMarkInfo() {
|
||||
//添加三个水印,位置坐标不同
|
||||
WaterMarkInfo waterMarkInfo = new WaterMarkInfo();
|
||||
waterMarkInfo.mWaterMarkPath = FileUtil.combinePaths(FileUtil.getInternalFilesFolder(getBaseContext()), "alivc_resource/watermark.png");
|
||||
WaterMarkInfo waterMarkInfo1 = new WaterMarkInfo();
|
||||
waterMarkInfo1.mWaterMarkPath = FileUtil.combinePaths(FileUtil.getInternalFilesFolder(getBaseContext()), "alivc_resource/watermark.png");
|
||||
waterMarkInfo.mWaterMarkCoordY += 0.2;
|
||||
WaterMarkInfo waterMarkInfo2 = new WaterMarkInfo();
|
||||
waterMarkInfo2.mWaterMarkPath = FileUtil.combinePaths(FileUtil.getInternalFilesFolder(getBaseContext()), "alivc_resource/watermark.png");
|
||||
waterMarkInfo2.mWaterMarkCoordY += 0.4;
|
||||
mWaterMarkInfos.add(waterMarkInfo);
|
||||
mWaterMarkInfos.add(waterMarkInfo1);
|
||||
mWaterMarkInfos.add(waterMarkInfo2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case CaptureActivity.REQ_CODE:
|
||||
switch (resultCode) {
|
||||
case RESULT_OK:
|
||||
mUrl.setText(data.getStringExtra(CaptureActivity.EXTRA_SCAN_RESULT)); //or do sth
|
||||
break;
|
||||
case RESULT_CANCELED:
|
||||
if (data != null) {
|
||||
// for some reason camera is not working correctly
|
||||
mUrl.setText(data.getStringExtra(CaptureActivity.EXTRA_SCAN_RESULT));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LivePushActivity.REQ_CODE_PUSH: {
|
||||
if (!mLivePushSettingView.getTargetVideoBitrateOnlyEditText().isEmpty() || Integer.parseInt(mLivePushSettingView.getTargetVideoBitrateOnlyHint()) != SharedPreferenceUtils.getTargetBit(getApplicationContext())) {
|
||||
mLivePushSettingView.setTargetVideoBitrateText(String.valueOf(SharedPreferenceUtils.getTargetBit(getApplicationContext())));
|
||||
}
|
||||
if (!mLivePushSettingView.getMinVideoBitrateOnlyEditText().isEmpty() || Integer.parseInt(mLivePushSettingView.getMinVideoBitrateOnlyHint()) != SharedPreferenceUtils.getMinBit(getApplicationContext())) {
|
||||
mLivePushSettingView.setMinVideoBitrateText(String.valueOf(SharedPreferenceUtils.getMinBit(getApplicationContext())));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
if (getCurrentFocus() != null && getCurrentFocus().getWindowToken() != null) {
|
||||
if (manager == null) {
|
||||
manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
}
|
||||
manager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
// SharedPreferenceUtils.clear(getApplicationContext());
|
||||
mLivePushSettingView.destroy();
|
||||
}
|
||||
|
||||
private void checkModelAndRun(final Runnable runnable) {
|
||||
runnable.run();
|
||||
// BeautyMenuMaterial.getInstance().checkModelReady(this, new OnDownloadUICallback() {
|
||||
// @Override
|
||||
// public void onDownloadStart(@StringRes int tipsResId) {
|
||||
// showProgressDialog(tipsResId);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onDownloadProgress(final float v) {
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onDownloadSuccess() {
|
||||
// hideProgressDialog();
|
||||
// runnable.run();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onDownloadError(@StringRes int tipsResId) {
|
||||
// hideProgressDialog();
|
||||
// showErrorTips(tipsResId);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
private void showProgressDialog(@StringRes int tipsResId) {
|
||||
if (null == mLoadingDialog) {
|
||||
mLoadingDialog = new AVLiveLoadingDialog(this).tip(getString(tipsResId));
|
||||
}
|
||||
if (!mLoadingDialog.isShowing()) {
|
||||
mLoadingDialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void hideProgressDialog() {
|
||||
if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
|
||||
mLoadingDialog.dismiss();
|
||||
mLoadingDialog = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void showErrorTips(@StringRes int tipsResId) {
|
||||
Toast.makeText(this, tipsResId, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private void startDownloadYUV() {
|
||||
// private PushConfigDialogImpl mPushConfigDialog = new PushConfigDialogImpl();
|
||||
long mCaptureDownloadId = ResourcesDownload.downloadCaptureYUV(this, new DownloadUtil.OnDownloadListener() {
|
||||
@Override
|
||||
public void onDownloadSuccess(long downloadId) {
|
||||
hideProgressDialog();
|
||||
ToastUtils.show("Download Success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadProgress(long downloadId, double percent) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadError(long downloadId, int errorCode, String errorMsg) {
|
||||
hideProgressDialog();
|
||||
ToastUtils.show(errorMsg);
|
||||
if (errorCode != DownloadManager.ERROR_FILE_ALREADY_EXISTS) {
|
||||
mLivePushSettingView.externDownloadError();
|
||||
}
|
||||
}
|
||||
});
|
||||
showProgressDialog(R.string.waiting_download_video_resources);
|
||||
}
|
||||
|
||||
private void jump2BackdoorActivity() {
|
||||
Intent intent = new Intent(this, BackDoorActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.alivc.live.baselive_push.ui;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alivc.live.baselive_push.R;
|
||||
import com.alivc.live.baselive_push.adapter.SoundEffectRecyclerViewAdapter;
|
||||
import com.alivc.live.baselive_push.bean.SoundEffectBean;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 音效设置 Fragment
|
||||
*/
|
||||
public class SoundEffectFragment extends Fragment {
|
||||
|
||||
private View inflate;
|
||||
private HashMap<Integer, SoundEffectBean> mDataMap;
|
||||
private SoundEffectRecyclerViewAdapter.OnSoundEffectItemClickListener mOnSoundEffectItemClickListener;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
Bundle arguments = getArguments();
|
||||
if (arguments != null) {
|
||||
mDataMap = (HashMap<Integer, SoundEffectBean>) arguments.getSerializable("args");
|
||||
}
|
||||
inflate = inflater.inflate(R.layout.fragment_sound_effect, container, false);
|
||||
return inflate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
RecyclerView mRecyclerView = inflate.findViewById(R.id.item_recycler_view);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||
SoundEffectRecyclerViewAdapter soundEffectRecyclerViewAdapter = new SoundEffectRecyclerViewAdapter(view.getContext(), mDataMap);
|
||||
mRecyclerView.setAdapter(soundEffectRecyclerViewAdapter);
|
||||
|
||||
soundEffectRecyclerViewAdapter.setOnSoundEffectItemClickListener(position -> {
|
||||
soundEffectRecyclerViewAdapter.setSelectIndex(position);
|
||||
if (mOnSoundEffectItemClickListener != null) {
|
||||
mOnSoundEffectItemClickListener.onSoundEffectItemClick(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setOnSoundEffectItemClickListener(SoundEffectRecyclerViewAdapter.OnSoundEffectItemClickListener listener) {
|
||||
this.mOnSoundEffectItemClickListener = listener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package com.alivc.live.baselive_push.ui.widget;
|
||||
|
||||
/**
|
||||
* **********************
|
||||
*
|
||||
* @Author bug machine
|
||||
* 创建时间: 2026/2/2 14:29
|
||||
* 用途
|
||||
* **********************
|
||||
*/
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
|
||||
public class BabeLiveRingLoadingView extends View {
|
||||
|
||||
// 画笔
|
||||
private final Paint ringPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint ringPaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint ringPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
// private final Paint logoPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
// private final Paint liveTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
// 颜色定义
|
||||
private final int ORANGE = Color.parseColor("#FF782D");
|
||||
private final int WHITE = Color.WHITE;
|
||||
|
||||
// 动画参数
|
||||
private float ringSweepAngle = 0f;
|
||||
private ValueAnimator animator;
|
||||
private ValueAnimator animator1;
|
||||
private ValueAnimator animator2;
|
||||
|
||||
private float ringSweepAngle1 = 0f;
|
||||
private float ringSweepAngle2 = 0f;
|
||||
|
||||
public BabeLiveRingLoadingView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public BabeLiveRingLoadingView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public BabeLiveRingLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// 初始化圆环画笔
|
||||
ringPaint.setColor(ORANGE);
|
||||
ringPaint.setStyle(Paint.Style.STROKE);
|
||||
ringPaint.setStrokeWidth(12f);
|
||||
ringPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
ringPaint.setAlpha(160);
|
||||
|
||||
ringPaint1.setColor(ORANGE);
|
||||
ringPaint1.setStyle(Paint.Style.STROKE);
|
||||
ringPaint1.setStrokeWidth(10f);
|
||||
ringPaint1.setStrokeCap(Paint.Cap.ROUND);
|
||||
ringPaint1.setAlpha(150);
|
||||
|
||||
|
||||
ringPaint2.setColor(ORANGE);
|
||||
ringPaint2.setStyle(Paint.Style.STROKE);
|
||||
ringPaint2.setStrokeWidth(10f);
|
||||
ringPaint2.setStrokeCap(Paint.Cap.ROUND);
|
||||
ringPaint2.setAlpha(140);
|
||||
|
||||
//
|
||||
// // 初始化Logo画笔
|
||||
// logoPaint.setColor(ORANGE);
|
||||
//
|
||||
// // 初始化LIVE文字画笔
|
||||
// liveTextPaint.setColor(WHITE);
|
||||
// liveTextPaint.setTextSize(48f);
|
||||
// liveTextPaint.setTextAlign(Paint.Align.CENTER);
|
||||
|
||||
|
||||
startAnima();
|
||||
}
|
||||
|
||||
private void startAnima() {
|
||||
startAnimation();
|
||||
startAnimation1();
|
||||
startAnimation2();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void stopAnima() {
|
||||
if(animator!=null){
|
||||
animator.cancel();
|
||||
animator = null;
|
||||
}
|
||||
if(animator1!=null){
|
||||
animator1.cancel();
|
||||
animator1 = null;
|
||||
|
||||
}
|
||||
if(animator2!=null){
|
||||
animator2.cancel();
|
||||
animator2 = null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void startAnimation() {
|
||||
animator = ValueAnimator.ofFloat(0f, 360f);
|
||||
animator.setDuration(1200);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.setRepeatCount(ValueAnimator.INFINITE);
|
||||
animator.addUpdateListener(animation -> {
|
||||
ringSweepAngle = (float) animation.getAnimatedValue();
|
||||
invalidate();
|
||||
});
|
||||
animator.start();
|
||||
}
|
||||
|
||||
|
||||
private void startAnimation1() {
|
||||
animator1 = ValueAnimator.ofFloat(360f, 0f);
|
||||
animator1.setDuration(1500);
|
||||
animator1.setInterpolator(new DecelerateInterpolator());
|
||||
animator1.setRepeatCount(ValueAnimator.INFINITE);
|
||||
animator1.addUpdateListener(animation -> {
|
||||
ringSweepAngle1 = (float) animation.getAnimatedValue();
|
||||
invalidate();
|
||||
});
|
||||
animator1.start();
|
||||
}
|
||||
|
||||
|
||||
private void startAnimation2() {
|
||||
animator2 = ValueAnimator.ofFloat(0f, 360f);
|
||||
animator2.setDuration(1800);
|
||||
animator2.setInterpolator(new AccelerateInterpolator());
|
||||
animator2.setRepeatCount(ValueAnimator.INFINITE);
|
||||
animator2.addUpdateListener(animation -> {
|
||||
ringSweepAngle2 = (float) animation.getAnimatedValue();
|
||||
invalidate();
|
||||
});
|
||||
animator2.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
int centerX = getWidth() / 2;
|
||||
int centerY = getHeight() / 2;
|
||||
int logoSize = Math.min(getWidth(), getHeight()) * 3 / 5;
|
||||
int ringRadius = Math.max(logoSize / 2 + 40, getWidth() / 2 - 30);
|
||||
|
||||
int ringRadius1 = Math.max(logoSize / 2 + 25, getWidth() / 2 - 60);
|
||||
|
||||
|
||||
int ringRadius2 = Math.max(logoSize / 2, getWidth() / 2 - 90);
|
||||
|
||||
// 绘制背景旋转圆环
|
||||
RectF ringRect = new RectF(
|
||||
centerX - ringRadius,
|
||||
centerY - ringRadius,
|
||||
centerX + ringRadius,
|
||||
centerY + ringRadius
|
||||
);
|
||||
|
||||
// 绘制背景旋转圆环
|
||||
RectF ringRect1 = new RectF(
|
||||
centerX - ringRadius1,
|
||||
centerY - ringRadius1,
|
||||
centerX + ringRadius1,
|
||||
centerY + ringRadius1
|
||||
);
|
||||
|
||||
// 绘制背景旋转圆环
|
||||
RectF ringRect2 = new RectF(
|
||||
centerX - ringRadius2,
|
||||
centerY - ringRadius2,
|
||||
centerX + ringRadius2,
|
||||
centerY + ringRadius2
|
||||
);
|
||||
canvas.drawArc(ringRect, -90, ringSweepAngle, false, ringPaint);
|
||||
canvas.drawArc(ringRect1, 0, ringSweepAngle1, false, ringPaint1);
|
||||
canvas.drawArc(ringRect2, 90, ringSweepAngle2, false, ringPaint2);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
if (animator != null) animator.cancel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
package com.alivc.live.baselive_push.ui.widget;
|
||||
|
||||
import static com.alivc.live.pusher.AlivcLivePushConstants.DEFAULT_VALUE_PREVIEW_MIRROR;
|
||||
import static com.alivc.live.pusher.AlivcLivePushConstants.DEFAULT_VALUE_PUSH_MIRROR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Color;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.alivc.live.commonui.avdialog.AVLiveBaseBottomSheetDialog;
|
||||
import com.alivc.live.commonui.configview.LivePushResolutionView;
|
||||
import com.alivc.live.baselive_push.R;
|
||||
import com.alivc.live.commonbiz.SharedPreferenceUtils;
|
||||
import com.alivc.live.pusher.AlivcPreviewDisplayMode;
|
||||
import com.alivc.live.pusher.AlivcQualityModeEnum;
|
||||
import com.alivc.live.commonutils.DensityUtil;
|
||||
import com.alivc.live.pusher.AlivcResolutionEnum;
|
||||
|
||||
public class PushMoreConfigBottomSheetLive extends AVLiveBaseBottomSheetDialog implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
||||
|
||||
private EditText mTargetRate = null;
|
||||
private EditText mMinRate = null;
|
||||
private Switch mPushMirror;
|
||||
private Switch mPreviewMirror;
|
||||
private TextView mPreviewMode;
|
||||
private OnMoreConfigListener mOnMoreConfigListener;
|
||||
private int mQualityMode = 0;
|
||||
private int mDisplayFit;
|
||||
private View mConfigListLn;
|
||||
private View mOrientationLn;
|
||||
private View mRootView;
|
||||
private View mDisplayModeFull;
|
||||
private View mDisplayModeFit;
|
||||
private View mDisplayModeCut;
|
||||
private View mOrientationBack;
|
||||
private LivePushResolutionView mLivePushResolutionView;
|
||||
|
||||
public PushMoreConfigBottomSheetLive(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public PushMoreConfigBottomSheetLive(Context context, int theme) {
|
||||
super(context, theme);
|
||||
}
|
||||
|
||||
protected PushMoreConfigBottomSheetLive(Context context, boolean cancelable, OnCancelListener cancelListener) {
|
||||
super(context, cancelable, cancelListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View getContentView() {
|
||||
mRootView = getLayoutInflater().inflate(R.layout.push_more, null, false);
|
||||
mTargetRate = mRootView.findViewById(R.id.target_rate_edit);
|
||||
mMinRate = mRootView.findViewById(R.id.min_rate_edit);
|
||||
|
||||
mPushMirror = mRootView.findViewById(R.id.push_mirror_switch);
|
||||
mPreviewMirror = mRootView.findViewById(R.id.preview_mirror_switch);
|
||||
mPreviewMode = mRootView.findViewById(R.id.setting_display_mode);
|
||||
mPushMirror.setChecked(SharedPreferenceUtils.isPushMirror(getContext().getApplicationContext(), DEFAULT_VALUE_PUSH_MIRROR));
|
||||
mPreviewMirror.setChecked(SharedPreferenceUtils.isPreviewMirror(getContext().getApplicationContext(), DEFAULT_VALUE_PREVIEW_MIRROR));
|
||||
mPushMirror.setOnCheckedChangeListener(this);
|
||||
mPreviewMirror.setOnCheckedChangeListener(this);
|
||||
|
||||
|
||||
mPreviewMode.setOnClickListener(this);
|
||||
mTargetRate.setText(String.valueOf(SharedPreferenceUtils.getTargetBit(getContext().getApplicationContext())));
|
||||
mMinRate.setText(String.valueOf(SharedPreferenceUtils.getMinBit(getContext().getApplicationContext())));
|
||||
|
||||
mTargetRate.setHint(String.valueOf(SharedPreferenceUtils.getHintTargetBit(getContext().getApplicationContext())));
|
||||
mMinRate.setHint(String.valueOf(SharedPreferenceUtils.getHintMinBit(getContext().getApplicationContext())));
|
||||
if (mQualityMode != AlivcQualityModeEnum.QM_CUSTOM.getQualityMode()) {
|
||||
mTargetRate.setFocusable(false);
|
||||
mMinRate.setFocusable(false);
|
||||
mTargetRate.setFocusableInTouchMode(false);
|
||||
mMinRate.setFocusableInTouchMode(false);
|
||||
mMinRate.setTextColor(Color.GRAY);
|
||||
mTargetRate.setTextColor(Color.GRAY);
|
||||
} else {
|
||||
mMinRate.setBackgroundColor(Color.WHITE);
|
||||
mTargetRate.setBackgroundColor(Color.WHITE);
|
||||
mTargetRate.setFocusable(true);
|
||||
mMinRate.setFocusable(true);
|
||||
mTargetRate.setFocusableInTouchMode(true);
|
||||
mMinRate.setFocusableInTouchMode(true);
|
||||
mTargetRate.requestFocus();
|
||||
mMinRate.requestFocus();
|
||||
}
|
||||
mConfigListLn = mRootView.findViewById(R.id.config_list);
|
||||
mOrientationLn = mRootView.findViewById(R.id.orientation_list);
|
||||
mDisplayModeFull = mRootView.findViewById(R.id.full);
|
||||
mDisplayModeFit = mRootView.findViewById(R.id.fit);
|
||||
mDisplayModeCut = mRootView.findViewById(R.id.cut);
|
||||
mOrientationBack = mRootView.findViewById(R.id.back);
|
||||
mDisplayModeFull.setOnClickListener(this);
|
||||
mDisplayModeFit.setOnClickListener(this);
|
||||
mDisplayModeCut.setOnClickListener(this);
|
||||
mOrientationBack.setOnClickListener(this);
|
||||
|
||||
mRootView.findViewById(R.id.cancel).setOnClickListener(this);
|
||||
mRootView.findViewById(R.id.confirm_button).setOnClickListener(this);
|
||||
mDisplayFit = SharedPreferenceUtils.getDisplayFit(getContext().getApplicationContext(),
|
||||
AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FIT.getPreviewDisplayMode());
|
||||
|
||||
if (mDisplayFit == AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_SCALE_FILL.getPreviewDisplayMode()) {
|
||||
onClick(mDisplayModeFull);
|
||||
} else if (mDisplayFit == AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FIT.getPreviewDisplayMode()) {
|
||||
onClick(mDisplayModeFit);
|
||||
} else if (mDisplayFit == AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FILL.getPreviewDisplayMode()) {
|
||||
onClick(mDisplayModeCut);
|
||||
}
|
||||
|
||||
mLivePushResolutionView = mRootView.findViewById(R.id.live_push_resolution);
|
||||
mLivePushResolutionView.setOnResolutionChangedListener(resolutionEnum -> {
|
||||
if (mOnMoreConfigListener != null) {
|
||||
mOnMoreConfigListener.onResolutionChanged(resolutionEnum);
|
||||
}
|
||||
});
|
||||
|
||||
return mRootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ViewGroup.LayoutParams getContentLayoutParams() {
|
||||
return new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DensityUtil.dip2px(getContext(), 304));
|
||||
}
|
||||
|
||||
|
||||
public void setQualityMode(int mode) {
|
||||
this.mQualityMode = mode;
|
||||
if (mTargetRate == null || mMinRate == null) {
|
||||
return;
|
||||
}
|
||||
if (mQualityMode != AlivcQualityModeEnum.QM_CUSTOM.getQualityMode()) {
|
||||
mTargetRate.setFocusable(false);
|
||||
mMinRate.setFocusable(false);
|
||||
mTargetRate.setFocusableInTouchMode(false);
|
||||
mMinRate.setFocusableInTouchMode(false);
|
||||
mMinRate.setBackgroundColor(Color.GRAY);
|
||||
mTargetRate.setBackgroundColor(Color.GRAY);
|
||||
} else {
|
||||
mMinRate.setBackgroundColor(Color.WHITE);
|
||||
mTargetRate.setBackgroundColor(Color.WHITE);
|
||||
mTargetRate.setFocusable(true);
|
||||
mMinRate.setFocusable(true);
|
||||
mTargetRate.setFocusableInTouchMode(true);
|
||||
mMinRate.setFocusableInTouchMode(true);
|
||||
mTargetRate.requestFocus();
|
||||
mMinRate.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
if (id == R.id.confirm_button || id == R.id.cancel) {
|
||||
dismiss();
|
||||
} else if (id == R.id.setting_display_mode) {
|
||||
mConfigListLn.setVisibility(View.GONE);
|
||||
mOrientationLn.setVisibility(View.VISIBLE);
|
||||
} else if (id == R.id.back) {
|
||||
mOrientationLn.setVisibility(View.GONE);
|
||||
mConfigListLn.setVisibility(View.VISIBLE);
|
||||
} else if (id == R.id.full) {
|
||||
mRootView.findViewById(R.id.cut_fit).setVisibility(View.GONE);
|
||||
mRootView.findViewById(R.id.cut_selected).setVisibility(View.GONE);
|
||||
mRootView.findViewById(R.id.full_fit).setVisibility(View.VISIBLE);
|
||||
mPreviewMode.setText(R.string.display_mode_full);
|
||||
if (mOnMoreConfigListener != null) {
|
||||
mOnMoreConfigListener.onDisplayModeChanged(AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_SCALE_FILL);
|
||||
}
|
||||
SharedPreferenceUtils.setDisplayFit(getContext(), AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_SCALE_FILL.getPreviewDisplayMode());
|
||||
} else if (id == R.id.fit) {
|
||||
mRootView.findViewById(R.id.full_fit).setVisibility(View.GONE);
|
||||
mRootView.findViewById(R.id.cut_selected).setVisibility(View.GONE);
|
||||
mRootView.findViewById(R.id.cut_fit).setVisibility(View.VISIBLE);
|
||||
mPreviewMode.setText(R.string.display_mode_fit);
|
||||
if (mOnMoreConfigListener != null) {
|
||||
mOnMoreConfigListener.onDisplayModeChanged(AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FIT);
|
||||
}
|
||||
SharedPreferenceUtils.setDisplayFit(getContext(), AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FIT.getPreviewDisplayMode());
|
||||
} else if (id == R.id.cut) {
|
||||
mRootView.findViewById(R.id.full_fit).setVisibility(View.GONE);
|
||||
mRootView.findViewById(R.id.cut_fit).setVisibility(View.GONE);
|
||||
mRootView.findViewById(R.id.cut_selected).setVisibility(View.VISIBLE);
|
||||
mPreviewMode.setText(R.string.display_mode_cut);
|
||||
if (mOnMoreConfigListener != null) {
|
||||
mOnMoreConfigListener.onDisplayModeChanged(AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FILL);
|
||||
}
|
||||
SharedPreferenceUtils.setDisplayFit(getContext(), AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FILL.getPreviewDisplayMode());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setOnMoreConfigListener(OnMoreConfigListener onMoreConfigListener) {
|
||||
mOnMoreConfigListener = onMoreConfigListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
int id = buttonView.getId();
|
||||
try {
|
||||
if (id == R.id.push_mirror_switch) {
|
||||
if (mOnMoreConfigListener != null) {
|
||||
mOnMoreConfigListener.onPushMirror(isChecked);
|
||||
}
|
||||
SharedPreferenceUtils.setPushMirror(getContext().getApplicationContext(), isChecked);
|
||||
} else if (id == R.id.preview_mirror_switch) {
|
||||
if (mOnMoreConfigListener != null) {
|
||||
mOnMoreConfigListener.onPreviewMirror(isChecked);
|
||||
}
|
||||
SharedPreferenceUtils.setPreviewMirror(getContext().getApplicationContext(), isChecked);
|
||||
} else if (id == R.id.autofocus_switch) {
|
||||
if (mOnMoreConfigListener != null) {
|
||||
mOnMoreConfigListener.onAutoFocus(isChecked);
|
||||
}
|
||||
SharedPreferenceUtils.setAutofocus(getContext().getApplicationContext(), isChecked);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
showDialog(getContext(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void showDialog(final Context context, final String message) {
|
||||
if (context == null || message == null) {
|
||||
return;
|
||||
}
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (context != null) {
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
|
||||
dialog.setTitle(context.getString(R.string.dialog_title));
|
||||
dialog.setMessage(message);
|
||||
dialog.setNegativeButton(context.getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getResolutionWidth() {
|
||||
return mLivePushResolutionView.getSelfDefineWidth();
|
||||
}
|
||||
|
||||
public int getResolutionHeight() {
|
||||
return mLivePushResolutionView.getSelfDefineHeight();
|
||||
}
|
||||
|
||||
public interface OnMoreConfigListener {
|
||||
void onDisplayModeChanged(AlivcPreviewDisplayMode mode);
|
||||
|
||||
void onPushMirror(boolean state);
|
||||
|
||||
void onPreviewMirror(boolean state);
|
||||
|
||||
void onAutoFocus(boolean state);
|
||||
|
||||
void onAddDynamic();
|
||||
|
||||
void onRemoveDynamic();
|
||||
|
||||
void onResolutionChanged(AlivcResolutionEnum resolutionEnum);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
package com.alivc.live.baselive_push.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alivc.live.commonui.avdialog.AVLiveBaseBottomSheetDialog;
|
||||
import com.alivc.live.commonui.bean.MusicInfo;
|
||||
import com.alivc.live.baselive_push.R;
|
||||
import com.alivc.live.baselive_push.adapter.MusicSelectAdapter;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class PushMusicBottomSheetLive extends AVLiveBaseBottomSheetDialog implements View.OnClickListener, CompoundButton.OnCheckedChangeListener, SeekBar.OnSeekBarChangeListener, MusicSelectAdapter.OnItemClick {
|
||||
private OnMusicSelectListener mOnMusicSelectListener;
|
||||
private MusicSelectAdapter mMusicAdapter;
|
||||
private Switch mEarsBackSwitch;
|
||||
private Switch mAudioDenoiseSwitch;
|
||||
private Switch mAudioIntelligentDenoiseSwitch;
|
||||
private View mIconVolumeView;
|
||||
private View mIconPlayView;
|
||||
private View mIconLoopView;
|
||||
private SeekBar mAccompanimentBar;
|
||||
private SeekBar mVoiceBar;
|
||||
private ProgressBar mMusicProgress;
|
||||
private TextView mMusicName;
|
||||
private TextView mCurrentTime;
|
||||
private TextView mDuration;
|
||||
|
||||
public PushMusicBottomSheetLive(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public PushMusicBottomSheetLive(Context context, int theme) {
|
||||
super(context, theme);
|
||||
}
|
||||
|
||||
protected PushMusicBottomSheetLive(Context context, boolean cancelable, OnCancelListener cancelListener) {
|
||||
super(context, cancelable, cancelListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View getContentView() {
|
||||
View rootView = getLayoutInflater().inflate(R.layout.push_music_sheet, null, false);
|
||||
|
||||
mEarsBackSwitch = rootView.findViewById(R.id.ears_back);
|
||||
mAudioDenoiseSwitch = rootView.findViewById(R.id.audio_noise);
|
||||
mAudioIntelligentDenoiseSwitch = rootView.findViewById(R.id.audio_intelligent_denoise);
|
||||
mEarsBackSwitch.setOnCheckedChangeListener(this);
|
||||
mAudioDenoiseSwitch.setOnCheckedChangeListener(this);
|
||||
mAudioIntelligentDenoiseSwitch.setOnCheckedChangeListener(this);
|
||||
|
||||
mIconVolumeView = rootView.findViewById(R.id.img_volume);
|
||||
mIconPlayView = rootView.findViewById(R.id.img_play);
|
||||
mIconLoopView = rootView.findViewById(R.id.img_loop);
|
||||
rootView.findViewById(R.id.cancel).setOnClickListener(this);
|
||||
rootView.findViewById(R.id.confirm_button).setOnClickListener(this);
|
||||
mIconVolumeView.setOnClickListener(this);
|
||||
mIconPlayView.setOnClickListener(this);
|
||||
mIconLoopView.setOnClickListener(this);
|
||||
|
||||
mAccompanimentBar = rootView.findViewById(R.id.accompaniment_seekbar);
|
||||
mVoiceBar = rootView.findViewById(R.id.voice_seekbar);
|
||||
mAccompanimentBar.setOnSeekBarChangeListener(this);
|
||||
mVoiceBar.setOnSeekBarChangeListener(this);
|
||||
mMusicProgress = rootView.findViewById(R.id.resolution_seekbar);
|
||||
mMusicName = rootView.findViewById(R.id.music_name);
|
||||
mCurrentTime = rootView.findViewById(R.id.tv_current_time);
|
||||
mDuration = rootView.findViewById(R.id.tv_duration_time);
|
||||
updateButton(false);
|
||||
RecyclerView recyclerView = rootView.findViewById(R.id.music_list);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
if (mMusicAdapter == null) {
|
||||
mMusicAdapter = new MusicSelectAdapter(getContext());
|
||||
recyclerView.setAdapter(mMusicAdapter);
|
||||
mMusicAdapter.setOnItemClick(this::onItemClick);
|
||||
}
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ViewGroup.LayoutParams getContentLayoutParams() {
|
||||
return new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
int id = view.getId();
|
||||
try {
|
||||
if (id == R.id.img_play) {
|
||||
boolean pauseSelected = mIconPlayView.isSelected();
|
||||
mIconPlayView.setSelected(!pauseSelected);
|
||||
if (mOnMusicSelectListener != null) {
|
||||
mOnMusicSelectListener.onBGPlay(!pauseSelected);
|
||||
}
|
||||
|
||||
} else if (id == R.id.img_loop) {
|
||||
boolean loopSelected = mIconLoopView.isSelected();
|
||||
mIconLoopView.setSelected(!loopSelected);
|
||||
if (mOnMusicSelectListener != null) {
|
||||
mOnMusicSelectListener.onBGLoop(!loopSelected);
|
||||
}
|
||||
|
||||
} else if (id == R.id.img_volume) {
|
||||
boolean isSelect = mIconVolumeView.isSelected();
|
||||
mIconVolumeView.setSelected(!isSelect);
|
||||
if (mOnMusicSelectListener != null) {
|
||||
mOnMusicSelectListener.onMute(!isSelect);
|
||||
}
|
||||
mAccompanimentBar.setEnabled(isSelect);
|
||||
mVoiceBar.setEnabled(isSelect);
|
||||
} else if (id == R.id.cancel || id == R.id.confirm_button) {
|
||||
dismiss();
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
int id = buttonView.getId();
|
||||
if (id == R.id.ears_back) {
|
||||
if (mOnMusicSelectListener != null) {
|
||||
mOnMusicSelectListener.onBGMEarsBack(isChecked);
|
||||
}
|
||||
} else if (id == R.id.audio_noise) {
|
||||
if (mOnMusicSelectListener != null) {
|
||||
mOnMusicSelectListener.onAudioNoise(isChecked);
|
||||
}
|
||||
updateAudioDenoiseSwitchState();
|
||||
} else if (id == R.id.audio_intelligent_denoise) {
|
||||
if (mOnMusicSelectListener != null) {
|
||||
mOnMusicSelectListener.onAudioIntelligentNoise(isChecked);
|
||||
}
|
||||
updateAudioDenoiseSwitchState();
|
||||
}
|
||||
}
|
||||
|
||||
// 使用智能降噪,需关闭普通降噪;两者功能互斥使用
|
||||
private void updateAudioDenoiseSwitchState() {
|
||||
if (mAudioDenoiseSwitch == null || mAudioIntelligentDenoiseSwitch == null) {
|
||||
return;
|
||||
}
|
||||
boolean useCustom = mAudioDenoiseSwitch.isChecked();
|
||||
boolean useIntelligent = mAudioIntelligentDenoiseSwitch.isChecked();
|
||||
if (!useCustom && !useIntelligent) {
|
||||
mAudioDenoiseSwitch.setEnabled(true);
|
||||
mAudioIntelligentDenoiseSwitch.setEnabled(true);
|
||||
} else if (useCustom && !useIntelligent) {
|
||||
mAudioIntelligentDenoiseSwitch.setEnabled(false);
|
||||
} else if (!useCustom && useIntelligent) {
|
||||
mAudioDenoiseSwitch.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
try {
|
||||
int seekBarId = seekBar.getId();
|
||||
|
||||
if (mAccompanimentBar.getId() == seekBarId) {
|
||||
if (mOnMusicSelectListener != null) {
|
||||
mOnMusicSelectListener.onBGMVolume(progress);
|
||||
}
|
||||
} else if (mVoiceBar.getId() == seekBarId) {
|
||||
if (mOnMusicSelectListener != null) {
|
||||
mOnMusicSelectListener.onCaptureVolume(progress);
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
public void updateProgress(long progress, long totalTime) {
|
||||
mDuration.setText(formatTimeFromMs(totalTime));
|
||||
mCurrentTime.setText(formatTimeFromMs(progress));
|
||||
mMusicProgress.setProgress((int) progress);
|
||||
mMusicProgress.setMax((int) totalTime);
|
||||
}
|
||||
|
||||
private void updateButtonState(boolean bool) {
|
||||
updateButton(bool);
|
||||
mIconPlayView.setSelected(bool);
|
||||
}
|
||||
|
||||
private void updateButton(boolean bool) {
|
||||
mIconVolumeView.setEnabled(bool);
|
||||
mIconPlayView.setEnabled(bool);
|
||||
mIconLoopView.setEnabled(bool);
|
||||
|
||||
if (!bool) {
|
||||
mAccompanimentBar.setEnabled(false);
|
||||
mVoiceBar.setEnabled(false);
|
||||
} else {
|
||||
mAccompanimentBar.setEnabled(!mIconVolumeView.isSelected());
|
||||
mVoiceBar.setEnabled(!mIconVolumeView.isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnMusicSelectListener(OnMusicSelectListener onMusicSelectListener) {
|
||||
mOnMusicSelectListener = onMusicSelectListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(MusicInfo musicInfo, int position) {
|
||||
updateButtonState(position > 0);
|
||||
if (musicInfo != null) {
|
||||
setPlayMusicUiState(musicInfo);
|
||||
if (mOnMusicSelectListener != null) {
|
||||
mOnMusicSelectListener.onBgResource(musicInfo.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setPlayMusicUiState(@NonNull MusicInfo musicInfo) {
|
||||
mMusicName.setText(musicInfo.getMusicName());
|
||||
mMusicProgress.setProgress(0);
|
||||
}
|
||||
|
||||
public interface OnMusicSelectListener {
|
||||
void onBGMEarsBack(boolean state);
|
||||
|
||||
void onAudioNoise(boolean state);
|
||||
|
||||
void onEarphone(boolean state);
|
||||
|
||||
void onAudioIntelligentNoise(boolean state);
|
||||
|
||||
void onBGPlay(boolean state);
|
||||
|
||||
void onBgResource(String path);
|
||||
|
||||
void onBGLoop(boolean state);
|
||||
|
||||
void onMute(boolean state);
|
||||
|
||||
void onCaptureVolume(int progress);
|
||||
|
||||
void onBGMVolume(int progress);
|
||||
}
|
||||
|
||||
private static String formatTimeFromMs(long ms) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("mm:ss");
|
||||
formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
|
||||
String hms = formatter.format(ms);
|
||||
return hms;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.alivc.live.baselive_push.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.alivc.live.baselive_push.R;
|
||||
import com.alivc.live.baselive_push.adapter.OnSoundEffectChangedListener;
|
||||
import com.alivc.live.baselive_push.bean.SoundEffectBean;
|
||||
import com.alivc.live.baselive_push.ui.SoundEffectFragment;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
/**
|
||||
* 音效 View
|
||||
*/
|
||||
public class SoundEffectView extends FrameLayout {
|
||||
|
||||
private SoundEffectFragment mSoundEffectChangeVoiceFragment;
|
||||
private SoundEffectFragment mSoundEffectReverbFragment;
|
||||
private Fragment mCurrentFragment;
|
||||
private OnSoundEffectChangedListener mOnSoundEffectChangedListener;
|
||||
|
||||
public SoundEffectView(@NonNull Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public SoundEffectView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public SoundEffectView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.layout_sound_effect_view, this, true);
|
||||
initFragment();
|
||||
initTabLayout();
|
||||
}
|
||||
|
||||
private void initFragment() {
|
||||
mSoundEffectChangeVoiceFragment = new SoundEffectFragment();
|
||||
Bundle changeVoiceBundle = new Bundle();
|
||||
changeVoiceBundle.putSerializable("args", SoundEffectBean.SoundEffectChangeVoiceBean.getLivePushSoundEffectChangeVoice());
|
||||
mSoundEffectChangeVoiceFragment.setArguments(changeVoiceBundle);
|
||||
|
||||
mSoundEffectReverbFragment = new SoundEffectFragment();
|
||||
Bundle reverbBundle = new Bundle();
|
||||
reverbBundle.putSerializable("args",SoundEffectBean.SoundEffectReverb.getLivePushSoundEffectReverb());
|
||||
mSoundEffectReverbFragment.setArguments(reverbBundle);
|
||||
|
||||
switchFragment(mSoundEffectChangeVoiceFragment);
|
||||
|
||||
mSoundEffectChangeVoiceFragment.setOnSoundEffectItemClickListener(position -> {
|
||||
if (mOnSoundEffectChangedListener != null) {
|
||||
mOnSoundEffectChangedListener.onSoundEffectChangeVoiceModeSelected(position);
|
||||
}
|
||||
});
|
||||
|
||||
mSoundEffectReverbFragment.setOnSoundEffectItemClickListener(position -> {
|
||||
if (mOnSoundEffectChangedListener != null) {
|
||||
mOnSoundEffectChangedListener.onSoundEffectRevertBSelected(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initTabLayout() {
|
||||
TabLayout mTabLayout = findViewById(R.id.tab_layout);
|
||||
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
switch (tab.getPosition()) {
|
||||
case 0://变声
|
||||
switchFragment(mSoundEffectChangeVoiceFragment);
|
||||
break;
|
||||
case 1://环境音
|
||||
switchFragment(mSoundEffectReverbFragment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void switchFragment(Fragment targetFragment) {
|
||||
if (mCurrentFragment == targetFragment) {
|
||||
return;
|
||||
}
|
||||
FragmentTransaction fragmentTransaction = ((FragmentActivity) getContext()).getSupportFragmentManager().beginTransaction();
|
||||
if (!targetFragment.isAdded()) {
|
||||
if (mCurrentFragment != null) {
|
||||
fragmentTransaction.hide(mCurrentFragment);
|
||||
}
|
||||
fragmentTransaction
|
||||
.add(R.id.frame_layout, targetFragment)
|
||||
.commit();
|
||||
} else {
|
||||
if (mCurrentFragment != null) {
|
||||
fragmentTransaction.hide(mCurrentFragment);
|
||||
}
|
||||
fragmentTransaction
|
||||
.show(targetFragment)
|
||||
.commit();
|
||||
}
|
||||
mCurrentFragment = targetFragment;
|
||||
}
|
||||
|
||||
public void setOnSoundEffectChangedListener(OnSoundEffectChangedListener listener) {
|
||||
this.mOnSoundEffectChangedListener = listener;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.alivc.live.baselive_push.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Created by kiun_2007 on 2018/3/29.
|
||||
*/
|
||||
|
||||
public class StatusLayout extends LinearLayout {
|
||||
public StatusLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public StatusLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public StatusLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private int getStatusBarHeight(Context context) {
|
||||
int result = 0;
|
||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = context.getResources().getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
ViewGroup.LayoutParams lp = this.getLayoutParams();
|
||||
lp.width = -1;
|
||||
lp.height = getStatusBarHeight(getContext());
|
||||
this.setLayoutParams(lp);
|
||||
super.onAttachedToWindow();
|
||||
}
|
||||
}
|
||||
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/back_icon.png
Normal file
|
After Width: | Height: | Size: 565 B |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/camera_on.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/flash_off.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/flash_on.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 499 B |
|
After Width: | Height: | Size: 799 B |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/icon_check.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/loop_off.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/loop_on.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/music.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/music_pause.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/music_play.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/mute_off.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/mute_on.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/preview_off.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/preview_on.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/push_off.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/push_on.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/push_pause.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/repush_off.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/scan_icon.png
Normal file
|
After Width: | Height: | Size: 257 B |
BIN
LiveBasic/live_push/src/main/res/drawable-xxhdpi/screenshot.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/push_info_on"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/push_info_on"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<solid android:color="@color/sound_effect_background" />
|
||||
<size android:width="32dp" android:height="32dp" />
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_checked="false">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:topLeftRadius="5dp" android:bottomLeftRadius="5dp" />
|
||||
<solid android:color="@android:color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/switch_bar_on_color" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_checked="true">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:topLeftRadius="5dp" android:bottomLeftRadius="5dp" />
|
||||
<solid android:color="@color/switch_bar_on_color" />
|
||||
<stroke android:width="1dp" android:color="@color/switch_bar_on_color" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_checked="false">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@android:color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/switch_bar_on_color" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_checked="true">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/switch_bar_on_color" />
|
||||
<stroke android:width="1dp" android:color="@color/switch_bar_on_color" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/setting_more_on"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/setting_more_on"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/loop_on"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/loop_off"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/music_play"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/music_pause"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/mute_on"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/mute_off"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/preview_on"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/preview_off"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/push_on"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/push_off"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/repush_off"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/repush_off"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_checked="false">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:topRightRadius="5dp" android:bottomRightRadius="5dp" />
|
||||
<solid android:color="@android:color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/switch_bar_on_color" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_checked="true">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:topRightRadius="5dp" android:bottomRightRadius="5dp" />
|
||||
<solid android:color="@color/switch_bar_on_color" />
|
||||
<stroke android:width="1dp" android:color="@color/switch_bar_on_color" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/flash_on"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/flash_off"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="8dp" />
|
||||
<solid android:color="#1C1D22" />
|
||||
</shape>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="@dimen/alivc_common_5"/>
|
||||
<solid android:color="@color/text_true_color"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_selected="true" android:drawable="@drawable/push_pause"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/push_pause"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="true" android:color="#4DCFE1"/>
|
||||
<item android:state_selected="false" android:color="@color/text_black"/>
|
||||
</selector>
|
||||
26
LiveBasic/live_push/src/main/res/layout/activity_push.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- 互动模式下的预览view -->
|
||||
<FrameLayout
|
||||
android:id="@+id/preview_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/alivc_color_black"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!-- 普通模式(默认)下的预览view -->
|
||||
<SurfaceView
|
||||
android:id="@+id/preview_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/tv_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/item_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/item_root"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/alivc_common_padding_14"
|
||||
android:layout_marginEnd="@dimen/alivc_common_20"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="@id/item_sound_effect_title"
|
||||
app:layout_constraintStart_toStartOf="@id/item_sound_effect_title"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_sound_effect_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/alivc_common_41"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="@dimen/view_margin_10"
|
||||
android:textColor="@color/camera_panel_content"
|
||||
android:textSize="@dimen/camera_panel_content_text"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/iv_icon" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
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="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@color/menu_bg_color"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabIndicatorFullWidth="false"
|
||||
app:tabTextColor="@color/camera_panel_content"
|
||||
app:tabSelectedTextColor="@color/colorBaseStyle"
|
||||
app:tabIndicatorColor="@color/colorBaseStyle"
|
||||
app:tabIndicatorHeight="@dimen/alivc_common_padding_2"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sound_effect_change_voice"/>
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sound_effect_reverb"/>
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/alivc_common_padding_1"
|
||||
android:background="@color/white"
|
||||
app:layout_constraintTop_toBottomOf="@id/tab_layout" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/frame_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/view_margin_20"
|
||||
android:layout_marginBottom="@dimen/view_margin_20"
|
||||
app:layout_constraintTop_toBottomOf="@id/tab_layout"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="45dp"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/music_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/music_check"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:src="@drawable/icon_check"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
330
LiveBasic/live_push/src/main/res/layout/push_fragment.xml
Normal file
@@ -0,0 +1,330 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<com.alivc.live.baselive_push.ui.widget.StatusLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/staticLayout"/>
|
||||
<FrameLayout
|
||||
android:id="@+id/title_fy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_below="@id/staticLayout"
|
||||
android:layout_height="?actionBarSize">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/exit"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@mipmap/back_img"
|
||||
android:layout_centerVertical="true"
|
||||
android:scaleType="centerInside"
|
||||
android:layout_gravity="center_vertical" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/wating_push"
|
||||
android:textColor="@color/body_txt_color"
|
||||
android:textSize="18sp" />
|
||||
</FrameLayout>
|
||||
|
||||
<com.alivc.live.commonui.messageview.AutoScrollMessagesView
|
||||
android:id="@+id/v_messages"
|
||||
android:layout_below="@id/title_fy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="240dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp" />
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/scrollview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="116dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/top_bar_layout"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sound_effect_button"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="@drawable/icon_sound_effect_background"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_live_push_sound_effect"
|
||||
app:tint="@color/text_black" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/sound_effect_title"
|
||||
android:textColor="@color/wheel_text_color_1"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/beauty_button"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:src="@drawable/beauty_selector" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/beauty"
|
||||
android:textColor="@color/wheel_text_color_1"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/music"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:src="@drawable/music" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/backgroud_music"
|
||||
android:textColor="@color/wheel_text_color_1"
|
||||
android:textSize="10sp" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/flash"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:src="@drawable/selector_camera_flash" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/flash"
|
||||
android:textColor="@color/wheel_text_color_1"
|
||||
android:textSize="10sp" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/camera"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:src="@drawable/camera_on" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/camera"
|
||||
android:textColor="@color/wheel_text_color_1"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/snapshot"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:src="@drawable/screenshot" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="@string/snapshot"
|
||||
android:textColor="@color/wheel_text_color_1"
|
||||
android:textSize="10sp" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/bottom_scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="69dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="#66FCFCFD"
|
||||
android:overScrollMode="never">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/action_bar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="38dp"
|
||||
android:paddingEnd="0dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/preview_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawableTop="@drawable/preview_selector"
|
||||
android:drawablePadding="2dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/stop_preview_button"
|
||||
android:textColor="@drawable/tools_tip_selector"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/push_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawableTop="@drawable/push_selector"
|
||||
android:drawablePadding="2dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/start_push"
|
||||
android:textColor="@drawable/tools_tip_selector"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/opera_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawableTop="@drawable/stop_selector"
|
||||
android:drawablePadding="2dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/pause_button"
|
||||
android:textColor="@drawable/tools_tip_selector"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/restart_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawableTop="@drawable/repush_selector"
|
||||
android:drawablePadding="2dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/repush_button"
|
||||
android:textColor="@drawable/tools_tip_selector"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/more"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawableTop="@drawable/more_setting_selector"
|
||||
android:drawablePadding="2dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/more_setting_button"
|
||||
android:textColor="@drawable/tools_tip_selector"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/network_detect"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawableTop="@drawable/live_network_detect"
|
||||
android:drawablePadding="2dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/network_detect"
|
||||
android:textColor="@drawable/tools_tip_selector"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/data"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawableTop="@drawable/data_selector"
|
||||
android:drawablePadding="2dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/data_args"
|
||||
android:textColor="@drawable/tools_tip_selector"
|
||||
android:textSize="10sp" />
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
|
||||
<com.alivc.live.baselive_push.ui.widget.SoundEffectView
|
||||
android:id="@+id/sound_effect_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.aliyunsdk.queen.menu.QueenBeautyMenu
|
||||
android:id="@+id/beauty_beauty_menuPanel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_configuration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/bottom_scroll"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp">
|
||||
|
||||
<com.alivc.live.commonui.widgets.LivePushTextSwitch
|
||||
android:id="@+id/btn_show_custom_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.alivc.live.commonui.widgets.LivePushTextSwitch
|
||||
android:id="@+id/btn_local_record"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_manual_create_egl_context"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="6dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/manual_create_egl_context_tv"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="12dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.alivc.live.commonui.seiview.LivePusherSEIView
|
||||
android:id="@+id/sei_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/layout_configuration"
|
||||
android:padding="10dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
||||
420
LiveBasic/live_push/src/main/res/layout/push_more.xml
Normal file
@@ -0,0 +1,420 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#1C1D22"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/config_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="62dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="start"
|
||||
android:gravity="center"
|
||||
android:text="@string/pull_cancel"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="62dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/more_setting_button"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/confirm_button"
|
||||
android:layout_width="62dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="end"
|
||||
android:gravity="center"
|
||||
android:text="@string/btn_confirm"
|
||||
android:textColor="#4DCFE1"
|
||||
android:textSize="15sp" />
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="19dp"
|
||||
android:background="#141416" />
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_size_45"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/target_bitrate"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/target_rate_edit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="28dp"
|
||||
android:background="@null"
|
||||
android:hint="@string/target_rate_value"
|
||||
android:inputType="number"
|
||||
android:textColor="#747A8C"
|
||||
android:textColorHint="#747A8C"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:text="/kbps"
|
||||
android:textColor="#747A8C"
|
||||
android:textSize="11sp" />
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_size_45"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/min_bitrate"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/min_rate_edit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="28dp"
|
||||
android:background="@null"
|
||||
android:hint="@string/min_rate_value"
|
||||
android:inputType="number"
|
||||
android:textColor="#747A8C"
|
||||
android:textColorHint="#747A8C"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:text="/kbps"
|
||||
android:textColor="#747A8C"
|
||||
android:textSize="11sp" />
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_size_45"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/setting_push_mirror"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/push_mirror_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:textOff=""
|
||||
android:textOn=""
|
||||
android:thumb="@drawable/thumb"
|
||||
android:track="@drawable/track" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_size_45"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/setting_pre_mirror"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/preview_mirror_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:textOff=""
|
||||
android:textOn=""
|
||||
android:thumb="@drawable/thumb"
|
||||
android:track="@drawable/track" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="45dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/landscape_model"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/setting_display_mode"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="end"
|
||||
android:gravity="center_vertical|end"
|
||||
android:paddingEnd="23dp"
|
||||
android:text="@string/quality_resolution_first"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:src="@drawable/ic_live_arrow_right" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<com.alivc.live.commonui.configview.LivePushResolutionView
|
||||
android:id="@+id/live_push_resolution"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginBottom="50dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/orientation_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/back"
|
||||
android:drawableLeft="@drawable/ic_blue_back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="start"
|
||||
android:gravity="center"
|
||||
android:text="@string/more_setting_button"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="62dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/landscape_model"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="15sp" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="19dp"
|
||||
android:background="#141416" />
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/full"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="45dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/display_mode_full"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/full_fit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:src="@drawable/icon_check" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="45dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/display_mode_fit"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cut_fit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:src="@drawable/icon_check"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/cut"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="45dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/display_mode_cut"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cut_selected"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:src="@drawable/icon_check"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
373
LiveBasic/live_push/src/main/res/layout/push_music_sheet.xml
Normal file
@@ -0,0 +1,373 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#1C1D22"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginBottom="45dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="62dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="start"
|
||||
android:gravity="center"
|
||||
android:text="@string/pull_cancel"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/backgroud_music"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/confirm_button"
|
||||
android:layout_width="62dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="end"
|
||||
android:gravity="center"
|
||||
android:text="@string/btn_confirm"
|
||||
android:textColor="#4DCFE1"
|
||||
android:textSize="15sp" />
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="19dp"
|
||||
android:background="#141416" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_size_45"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/open_ears_back"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/ears_back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:textOff=""
|
||||
android:textOn=""
|
||||
android:thumb="@drawable/thumb"
|
||||
android:track="@drawable/track" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_size_45"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/open_audio_denoise"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/audio_noise"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:textOff=""
|
||||
android:textOn=""
|
||||
android:thumb="@drawable/thumb"
|
||||
android:track="@drawable/track" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_size_45"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="100dp"
|
||||
android:text="@string/open_audio_intelligent_denoise"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_30px" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/audio_intelligent_denoise"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:textOff=""
|
||||
android:textOn=""
|
||||
android:thumb="@drawable/thumb"
|
||||
android:track="@drawable/track" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="370dp"
|
||||
android:background="#141416">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="330dp"
|
||||
android:layout_margin="20dp"
|
||||
android:background="@drawable/shape_music_controll_bg"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/music_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="16sp" />
|
||||
<ImageView
|
||||
android:src="@drawable/ic_live_music_yinfu"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_gravity="end"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"/>
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/resolution_seekbar"
|
||||
style="@style/AVLive_ProgressBar_Horizontal_Style"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="3dp"
|
||||
android:layout_marginTop="54dp"
|
||||
android:max="100"
|
||||
android:maxHeight="5dp"
|
||||
android:min="0"
|
||||
android:minHeight="5dp"
|
||||
android:progressDrawable="@drawable/live_progress_horizontal_shape" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_current_time"
|
||||
android:layout_marginTop="76dp"
|
||||
android:textColor="#747A8C"
|
||||
android:textSize="12sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_duration_time"
|
||||
android:layout_marginTop="76dp"
|
||||
android:layout_gravity="end"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#747A8C"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_volume"
|
||||
android:layout_marginTop="110dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/music_volume_selector"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"/>
|
||||
<ImageView
|
||||
android:id="@+id/img_play"
|
||||
android:src="@drawable/music_play_selector"
|
||||
android:layout_marginTop="110dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:scaleType="fitXY"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"/>
|
||||
<ImageView
|
||||
android:id="@+id/img_loop"
|
||||
android:layout_marginTop="110dp"
|
||||
android:layout_gravity="end"
|
||||
android:src="@drawable/music_loop_selector"
|
||||
android:scaleType="fitXY"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"/>
|
||||
|
||||
<TextView
|
||||
android:text="@string/accompaniment"
|
||||
android:textSize="15sp"
|
||||
android:layout_marginTop="167dp"
|
||||
android:textColor="#FCFCFD"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/accompaniment_seekbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxHeight="5dp"
|
||||
android:minHeight="5dp"
|
||||
android:progress="50"
|
||||
android:layout_marginTop="200dp"
|
||||
android:theme="@style/Push_SeekBar_Style" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="246dp"
|
||||
android:text="@string/voice"
|
||||
android:textSize="15sp"
|
||||
android:textColor="#FCFCFD" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/voice_seekbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="279dp"
|
||||
android:maxHeight="5dp"
|
||||
android:minHeight="5dp"
|
||||
android:progress="50"
|
||||
android:theme="@style/Push_SeekBar_Style" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:visibility="gone"
|
||||
android:id="@+id/opera"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:text="@string/av_resolution_music_operations"
|
||||
android:textColor="@android:color/black"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="30dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/pause"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:background="@drawable/left_shape_selector"
|
||||
android:button="@null"
|
||||
android:gravity="center"
|
||||
android:text="@string/pause"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/stop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:background="@drawable/middle_shape_selector"
|
||||
android:button="@null"
|
||||
android:gravity="center"
|
||||
android:text="@string/start"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/loop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:background="@drawable/middle_shape_selector"
|
||||
android:button="@null"
|
||||
android:gravity="center"
|
||||
android:text="@string/close_loop"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/mute"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:background="@drawable/right_shape_selector"
|
||||
android:button="@null"
|
||||
android:checked="true"
|
||||
android:gravity="center"
|
||||
android:text="@string/open_mute"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
</RadioGroup>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:text="@string/music_list"
|
||||
android:textColor="#747A8C"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="20dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="39dp"/>
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/music_list"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
246
LiveBasic/live_push/src/main/res/layout/push_setting.xml
Normal file
@@ -0,0 +1,246 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout 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:background="@color/main_color"
|
||||
android:fitsSystemWindows="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/main_color"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/title_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?actionBarSize"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_back"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@mipmap/back_img" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_height_size_32"
|
||||
android:layout_marginEnd="@dimen/view_margin_10"
|
||||
android:background="#23262F"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/qr_code"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/view_margin_12"
|
||||
android:background="@drawable/scan_icon" />
|
||||
|
||||
|
||||
<EditText
|
||||
android:id="@+id/url_editor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_margin_22"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/view_margin_12"
|
||||
android:background="@null"
|
||||
android:ellipsize="end"
|
||||
android:hint="@string/view_string_hint_push_url"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/color_text_grey"
|
||||
android:textColorHint="@color/color_text_grey"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="45dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/tab_args_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tab_args_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="17dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="@string/push_args"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
<View
|
||||
android:id="@+id/tab_args_view"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="3dp"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:background="#4DCFE1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/tab_action_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tab_action_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="17dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="@string/stream_pusher_tip"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
<View
|
||||
android:id="@+id/tab_action_view"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="3dp"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:background="#4DCFE1"
|
||||
android:visibility="invisible" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:background="#3A3D48" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_interaction"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/model_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/live_push_mode"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_28px" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/live_push_mode"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/model_title"
|
||||
android:layout_marginTop="5dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatRadioButton
|
||||
android:id="@+id/push_mode_normal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/live_push_mode_normal"
|
||||
android:textColor="#FCFCFD" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatRadioButton
|
||||
android:id="@+id/push_mode_interaction"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/live_push_mode_interaction"
|
||||
android:textColor="#FCFCFD" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatRadioButton
|
||||
android:id="@+id/push_mode_raw_stream"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/live_push_mode_raw_stream"
|
||||
android:textColor="#FCFCFD" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<com.alivc.live.commonui.configview.LivePushSettingView
|
||||
android:id="@+id/push_setting_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/beginPublish"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginBottom="42dp"
|
||||
android:background="@drawable/shape_pysh_btn_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:text="@string/start_button"
|
||||
android:textColor="#FCFCFD"
|
||||
android:textSize="@dimen/font_size_36px"
|
||||
android:textStyle="normal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
android:background="@color/main_color">
|
||||
<RelativeLayout
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="300dp"
|
||||
android:layout_centerInParent="true">
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@mipmap/logo_left"/>
|
||||
<com.alivc.live.baselive_push.ui.widget.BabeLiveRingLoadingView
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="300dp"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
LiveBasic/live_push/src/main/res/mipmap-xxhdpi/back_img.png
Normal file
|
After Width: | Height: | Size: 903 B |
BIN
LiveBasic/live_push/src/main/res/mipmap-xxhdpi/logo_left.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
101
LiveBasic/live_push/src/main/res/values-en/strings.xml
Normal file
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="interaction_mode">Interaction Mode</string>
|
||||
<string name="live_push_mode">LivePush Mode</string>
|
||||
<string name="start_button">Start pushing</string>
|
||||
<string name="waiting_download_video_resources">waiting for download external video resources</string>
|
||||
<string name="live_push_mode_normal">Normal</string>
|
||||
<string name="live_push_mode_interaction">Interaction</string>
|
||||
<string name="live_push_mode_raw_stream">RawStream</string>
|
||||
|
||||
<string name="success">Success</string>
|
||||
<string name="failed">Failed</string>
|
||||
|
||||
<string name="pause_button">Pause</string>
|
||||
<string name="connecting_dialog_tips">pushing_wating</string>
|
||||
<string name="pushing">Ingesting...</string>
|
||||
|
||||
|
||||
<string name="beauty_off_tips">Retouching is disabled. Enable retouching and then retry.</string>
|
||||
<string name="add_dynamic_failed">Add dynamic failed, id=</string>
|
||||
<string name="start_preview">Start preview</string>
|
||||
<string name="stop_preview">Stop preview</string>
|
||||
<string name="stop_push">Stop pushing</string>
|
||||
<string name="pause_push">Pause</string>
|
||||
<string name="resume_push">Resume</string>
|
||||
<string name="restart_success">Restart successfully</string>
|
||||
|
||||
<string name="packet_lost">Package lost</string>
|
||||
<string name="connection_lost">Connection lost</string>
|
||||
<string name="network_poor">The network is unstable, please quit or try again</string>
|
||||
<string name="network_recovery">The network has recovered</string>
|
||||
<string name="reconnect_start">Start reconnecting</string>
|
||||
<string name="reconnect_fail">Reconnection failed</string>
|
||||
<string name="reconnect_success">Reconnection succeed</string>
|
||||
<string name="senddata_timeout">Sending data timeout</string>
|
||||
<string name="send_message">Send Message</string>
|
||||
<string name="bgm_open_failed">BGM File open Failed</string>
|
||||
<string name="reconnect">Reconnect</string>
|
||||
<string name="resume_button">Resume</string>
|
||||
|
||||
<string name="start_preview_button">Start preview</string>
|
||||
<string name="wating_push">Waiting for Stream Ingest...</string>
|
||||
<string name="backgroud_music">Background Music</string>
|
||||
<string name="flash">Flash</string>
|
||||
<string name="camera">Camera</string>
|
||||
<string name="snapshot">Snapshot</string>
|
||||
<string name="stop_preview_button">Stop preview</string>
|
||||
<string name="repush_button">Restart pushing</string>
|
||||
<string name="more_setting_button">More setting</string>
|
||||
<string name="data_args">Data Metrics</string>
|
||||
<string name="network_detect">Network Detect</string>
|
||||
<string name="local_info">Statistics on Local Videos</string>
|
||||
|
||||
<string name="close_ears_back">Close Ears</string>
|
||||
<string name="open_ears_back">Open Ears</string>
|
||||
<string name="open_audio_denoise">Audio Denoise</string>
|
||||
<string name="open_audio_intelligent_denoise">Audio Intelligent Denoise</string>
|
||||
<string name="accompaniment">Accompaniment</string>
|
||||
<string name="voice">Voice</string>
|
||||
<string name="av_resolution_music_operations">Music Operations</string>
|
||||
<string name="pause">Pause</string>
|
||||
<string name="resume">Resume</string>
|
||||
<string name="stop">Stop</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="close_loop">Close Loop</string>
|
||||
<string name="open_loop">Open Loop</string>
|
||||
<string name="close_mute">Close Mute</string>
|
||||
<string name="open_mute">Open Mute</string>
|
||||
<string name="music_list">Music List</string>
|
||||
<string name="no_music">No Music</string>
|
||||
<string name="internet_music">Internet music</string>
|
||||
|
||||
<string name="dialog_title">Error tips</string>
|
||||
<string name="ok">OK</string>
|
||||
|
||||
<string name="setting_audio_441">44.1KHz</string>
|
||||
<string name="setting_audio_320">32KHz</string>
|
||||
<string name="setting_audio_160">16KHz</string>
|
||||
|
||||
<string name="sound_effect_reverb_off">Off</string>
|
||||
<string name="sound_effect_reverb_vocal1">Vocal1</string>
|
||||
<string name="sound_effect_reverb_vocal2">Vocal2</string>
|
||||
<string name="sound_effect_reverb_bathroom">BathRoom</string>
|
||||
<string name="sound_effect_reverb_smallroom_bright">SmallRoom(bright)</string>
|
||||
<string name="sound_effect_reverb_smallroom_dark">SmallRoom(Dark)</string>
|
||||
<string name="sound_effect_reverb_mediumroom">MediumRoom</string>
|
||||
<string name="sound_effect_reverb_largeroom">LargeRoom</string>
|
||||
<string name="sound_effect_reverb_churchhall">ChurchHall</string>
|
||||
|
||||
<string name="sound_effect_title">Sound Effect</string>
|
||||
<string name="sound_effect_change_voice">Change Voice</string>
|
||||
<string name="sound_effect_reverb">Reverb</string>
|
||||
<string name="sound_effect_changevoice_off">Off</string>
|
||||
<string name="sound_effect_changevoice_oldman">Old_man</string>
|
||||
<string name="sound_effect_changevoice_babyboy">Baby_Boy</string>
|
||||
<string name="sound_effect_changevoice_babygirl">Baby_Girl</string>
|
||||
<string name="sound_effect_changevoice_robot">Robot</string>
|
||||
<string name="sound_effect_changevoice_daimo">Daimo</string>
|
||||
<string name="sound_effect_changevoice_ktv">KTV</string>
|
||||
<string name="sound_effect_changevoice_echo">Echo</string>
|
||||
</resources>
|
||||
101
LiveBasic/live_push/src/main/res/values-zh-rCN/strings.xml
Normal file
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="interaction_mode">互动模式</string>
|
||||
<string name="live_push_mode">推流模式</string>
|
||||
<string name="start_button">进入直播</string>
|
||||
<string name="waiting_download_video_resources">正在下载外部音视频资源中,请等待</string>
|
||||
<string name="live_push_mode_normal">普通模式</string>
|
||||
<string name="live_push_mode_interaction">互动模式</string>
|
||||
<string name="live_push_mode_raw_stream">推拉裸流</string>
|
||||
|
||||
<string name="success">成功</string>
|
||||
<string name="failed">失败</string>
|
||||
<string name="pause_button">暂停</string>
|
||||
<string name="connecting_dialog_tips">推流连接中,请稍后</string>
|
||||
<string name="pushing">推流中</string>
|
||||
<string name="beauty_off_tips">美颜开关关闭,请在设置开启后重试...</string>
|
||||
<string name="add_dynamic_failed">添加贴纸失败, id=</string>
|
||||
<string name="start_preview">开始预览</string>
|
||||
<string name="stop_preview">停止预览</string>
|
||||
<string name="stop_push">停止推流</string>
|
||||
<string name="pause_push">暂停</string>
|
||||
<string name="resume_push">恢复</string>
|
||||
<string name="restart_success">重启成功</string>
|
||||
|
||||
<string name="packet_lost">推流丢包通知</string>
|
||||
<string name="connection_lost">推流已断开</string>
|
||||
<string name="network_poor">网络差,请退出或者重连</string>
|
||||
<string name="network_recovery">网络恢复</string>
|
||||
<string name="reconnect_start">重连开始</string>
|
||||
<string name="reconnect_fail">重连失败</string>
|
||||
<string name="reconnect_success">重连成功</string>
|
||||
<string name="senddata_timeout">发送数据超时</string>
|
||||
<string name="send_message">发送消息</string>
|
||||
<string name="bgm_open_failed">音乐文件打开失败</string>
|
||||
<string name="reconnect">重连</string>
|
||||
<string name="resume_button">恢复</string>
|
||||
|
||||
|
||||
|
||||
<string name="start_preview_button">开始预览</string>
|
||||
<string name="wating_push">未推流</string>
|
||||
<string name="backgroud_music">背景音乐</string>
|
||||
<string name="flash">闪光灯</string>
|
||||
<string name="camera">摄像头</string>
|
||||
<string name="snapshot">截图</string>
|
||||
<string name="stop_preview_button">停止预览</string>
|
||||
<string name="repush_button">重新推流</string>
|
||||
<string name="more_setting_button">更多设置</string>
|
||||
<string name="data_args">数据指标</string>
|
||||
<string name="network_detect">网络探测</string>
|
||||
<string name="local_info">本地视频统计信息</string>
|
||||
|
||||
|
||||
<string name="close_ears_back">关耳返</string>
|
||||
<string name="open_ears_back">开耳返</string>
|
||||
<string name="open_audio_denoise">音频降噪</string>
|
||||
<string name="open_audio_intelligent_denoise">音频智能降噪</string>
|
||||
<string name="accompaniment">伴奏音量</string>
|
||||
<string name="voice">人声音量</string>
|
||||
<string name="av_resolution_music_operations">音乐操作</string>
|
||||
<string name="pause">暂停</string>
|
||||
<string name="resume">恢复</string>
|
||||
<string name="stop">停止</string>
|
||||
<string name="start">开始</string>
|
||||
<string name="close_loop">关循环</string>
|
||||
<string name="open_loop">开循环</string>
|
||||
<string name="close_mute">关静音</string>
|
||||
<string name="open_mute">开静音</string>
|
||||
<string name="music_list">音乐列表</string>
|
||||
<string name="no_music">无音乐</string>
|
||||
<string name="internet_music">网络音乐</string>
|
||||
|
||||
<string name="dialog_title">提示</string>
|
||||
<string name="ok">确定</string>
|
||||
|
||||
<string name="setting_audio_441">44.1KHz</string>
|
||||
<string name="setting_audio_320">32KHz</string>
|
||||
<string name="setting_audio_160">16KHz</string>
|
||||
|
||||
<string name="sound_effect_reverb_off">无</string>
|
||||
<string name="sound_effect_reverb_vocal1">人声I</string>
|
||||
<string name="sound_effect_reverb_vocal2">人声II</string>
|
||||
<string name="sound_effect_reverb_bathroom">澡堂</string>
|
||||
<string name="sound_effect_reverb_smallroom_bright">明亮小房间</string>
|
||||
<string name="sound_effect_reverb_smallroom_dark">黑暗小房间</string>
|
||||
<string name="sound_effect_reverb_mediumroom">中等房间</string>
|
||||
<string name="sound_effect_reverb_largeroom">大房间</string>
|
||||
<string name="sound_effect_reverb_churchhall">教堂走廊</string>
|
||||
|
||||
<string name="sound_effect_title">音效</string>
|
||||
<string name="sound_effect_change_voice">变声</string>
|
||||
<string name="sound_effect_reverb">混响</string>
|
||||
<string name="sound_effect_changevoice_off">无</string>
|
||||
<string name="sound_effect_changevoice_oldman">老人</string>
|
||||
<string name="sound_effect_changevoice_babyboy">男孩</string>
|
||||
<string name="sound_effect_changevoice_babygirl">女孩</string>
|
||||
<string name="sound_effect_changevoice_robot">机器人</string>
|
||||
<string name="sound_effect_changevoice_daimo">大魔王</string>
|
||||
<string name="sound_effect_changevoice_ktv">KTV</string>
|
||||
<string name="sound_effect_changevoice_echo">回声</string>
|
||||
</resources>
|
||||
112
LiveBasic/live_push/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
|
||||
<string name="interaction_mode">Interaction Mode</string>
|
||||
<string name="live_push_mode">LivePush Mode</string>
|
||||
<string name="start_button">Start pushing</string>
|
||||
<string name="waiting_download_video_resources">waiting for download external video resources</string>
|
||||
<string name="live_push_mode_normal">Normal</string>
|
||||
<string name="live_push_mode_interaction">Interaction</string>
|
||||
<string name="live_push_mode_raw_stream">RawStream</string>
|
||||
|
||||
<string name="success">Success</string>
|
||||
<string name="failed">Failed</string>
|
||||
|
||||
<string name="pause_button">Pause</string>
|
||||
|
||||
<string name="connecting_dialog_tips">pushing_wating</string>
|
||||
<string name="pushing">Ingesting...</string>
|
||||
|
||||
|
||||
<string name="beauty_off_tips">Retouching is disabled. Enable retouching and then retry.</string>
|
||||
<string name="add_dynamic_failed">Add dynamic failed, id=</string>
|
||||
<string name="start_preview">Start preview</string>
|
||||
<string name="stop_preview">Stop preview</string>
|
||||
<string name="stop_push">Stop pushing</string>
|
||||
<string name="pause_push">Pause</string>
|
||||
<string name="resume_push">Resume</string>
|
||||
<string name="restart_success">Restart successfully</string>
|
||||
|
||||
<string name="packet_lost">Package lost</string>
|
||||
<string name="connection_lost">Connection lost</string>
|
||||
<string name="network_poor">The network is unstable, please quit or try again</string>
|
||||
<string name="network_recovery">The network has recovered</string>
|
||||
<string name="reconnect_start">Start reconnecting</string>
|
||||
<string name="reconnect_fail">Reconnection failed</string>
|
||||
<string name="reconnect_success">Reconnection succeed</string>
|
||||
<string name="senddata_timeout">Sending data timeout</string>
|
||||
<string name="send_message">Send Message</string>
|
||||
<string name="bgm_open_failed">BGM File open Failed</string>
|
||||
<string name="reconnect">Reconnect</string>
|
||||
<string name="resume_button">Resume</string>
|
||||
|
||||
<string name="start_preview_button">Start preview</string>
|
||||
<string name="wating_push">Waiting for Stream Ingest...</string>
|
||||
<string name="backgroud_music">Background Music</string>
|
||||
<string name="flash">Flash</string>
|
||||
<string name="camera">Camera</string>
|
||||
<string name="snapshot">Snapshot</string>
|
||||
<string name="stop_preview_button">Stop preview</string>
|
||||
<string name="repush_button">Restart pushing</string>
|
||||
<string name="more_setting_button">More setting</string>
|
||||
<string name="data_args">Data Metrics</string>
|
||||
<string name="network_detect">Network Detect</string>
|
||||
<string name="local_info">Statistics on Local Videos</string>
|
||||
|
||||
<string name="close_ears_back">Close Ears</string>
|
||||
<string name="open_ears_back">Open Ears</string>
|
||||
<string name="open_audio_denoise">Audio Denoise</string>
|
||||
<string name="open_audio_intelligent_denoise">Audio Intelligent Denoise</string>
|
||||
<string name="accompaniment">Accompaniment</string>
|
||||
<string name="voice">Voice</string>
|
||||
<string name="av_resolution_music_operations">Music Operations</string>
|
||||
<string name="pause">Pause</string>
|
||||
<string name="resume">Resume</string>
|
||||
<string name="stop">Stop</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="close_loop">Close Loop</string>
|
||||
<string name="open_loop">Open Loop</string>
|
||||
<string name="close_mute">Close Mute</string>
|
||||
<string name="open_mute">Open Mute</string>
|
||||
<string name="music_list">Music List</string>
|
||||
<string name="no_music">No Music</string>
|
||||
<string name="internet_music">Internet music</string>
|
||||
|
||||
<string name="dialog_title">Error tips</string>
|
||||
<string name="ok">OK</string>
|
||||
|
||||
<string name="setting_audio_441">44.1KHz</string>
|
||||
<string name="setting_audio_320">32KHz</string>
|
||||
<string name="setting_audio_160">16KHz</string>
|
||||
|
||||
<string name="sound_effect_reverb_off">Off</string>
|
||||
<string name="sound_effect_reverb_vocal1">Vocal1</string>
|
||||
<string name="sound_effect_reverb_vocal2">Vocal2</string>
|
||||
<string name="sound_effect_reverb_bathroom">BathRoom</string>
|
||||
<string name="sound_effect_reverb_smallroom_bright">SmallRoom(bright)</string>
|
||||
<string name="sound_effect_reverb_smallroom_dark">SmallRoom(Dark)</string>
|
||||
<string name="sound_effect_reverb_mediumroom">MediumRoom</string>
|
||||
<string name="sound_effect_reverb_largeroom">LargeRoom</string>
|
||||
<string name="sound_effect_reverb_churchhall">ChurchHall</string>
|
||||
|
||||
<string name="sound_effect_title">Sound Effect</string>
|
||||
<string name="sound_effect_change_voice">Change Voice</string>
|
||||
<string name="sound_effect_reverb">Reverb</string>
|
||||
<string name="sound_effect_changevoice_off">Off</string>
|
||||
<string name="sound_effect_changevoice_oldman">Old_man</string>
|
||||
<string name="sound_effect_changevoice_babyboy">Baby_Boy</string>
|
||||
<string name="sound_effect_changevoice_babygirl">Baby_Girl</string>
|
||||
<string name="sound_effect_changevoice_robot">Robot</string>
|
||||
<string name="sound_effect_changevoice_daimo">Daimo</string>
|
||||
<string name="sound_effect_changevoice_ktv">KTV</string>
|
||||
<string name="sound_effect_changevoice_echo">Echo</string>
|
||||
|
||||
|
||||
<style name="AppThemePlayer" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<item name="android:windowTranslucentNavigation">true</item>
|
||||
<item name="android:windowBackground">@color/main_color</item>
|
||||
</style>
|
||||
|
||||
|
||||
</resources>
|
||||