new
1
.idea/gradle.xml
generated
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
|
||||
8
.idea/misc.xml
generated
@@ -4,7 +4,15 @@
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="../../../../layout/custom_preview.xml" value="0.21076923076923076" />
|
||||
<entry key="app/src/main/res/drawable/liveplayer_content_bg.xml" value="0.20364583333333333" />
|
||||
<entry key="app/src/main/res/drawable/liveplayer_video_cache_progress.xml" value="0.20364583333333333" />
|
||||
<entry key="app/src/main/res/drawable/livepusher_btn_bg.xml" value="0.20364583333333333" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.2115036231884058" />
|
||||
<entry key="app/src/main/res/layout/liveplayer_top_bar_layout.xml" value="0.1875" />
|
||||
<entry key="app/src/main/res/layout/livepusher_activity_live_pusher_entrance.xml" value="0.1875" />
|
||||
<entry key="app/src/main/res/layout/livepusher_top_bar_layout.xml" value="0.1875" />
|
||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.20364583333333333" />
|
||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.20364583333333333" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -7,7 +7,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "net.spacen.xxh_video"
|
||||
minSdk 21
|
||||
minSdk 19
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
@@ -50,6 +50,9 @@ dependencies {
|
||||
|
||||
implementation 'org.greenrobot:eventbus:3.1.1'
|
||||
|
||||
implementation 'com.kyleduo.switchbutton:library:2.0.0'
|
||||
|
||||
|
||||
//implementation 'com.github.MZCretin:AutoUpdateProject:latest_version'
|
||||
|
||||
testImplementation 'junit:junit:4.+'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.spacen.xxh_video;
|
||||
package net.spacen.xxh-video;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="CameraPushEntranceActivity" />
|
||||
|
||||
<service android:name="org.eclipse.paho.android.service.MqttService" />
|
||||
<service android:name=".MyMqttService"/> <!--MyMqttService-->
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
package net.spacen.xxh_video;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* 摄像头推流入口页面,主要用于生成推流地址
|
||||
*/
|
||||
public class CameraPushEntranceActivity extends Activity {
|
||||
|
||||
private static final int ACTIVITY_SCAN_REQUEST_CODE = 1;
|
||||
private static final int REQUEST_CODE = 100;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private EditText mEditInputURL;
|
||||
|
||||
@Override
|
||||
protected void onCreate( Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mContext = this;
|
||||
setContentView(R.layout.livepusher_activity_live_pusher_entrance);
|
||||
initViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == ACTIVITY_SCAN_REQUEST_CODE && resultCode == RESULT_OK) {
|
||||
String scanURL = data.getStringExtra(Constants.INTENT_SCAN_RESULT);
|
||||
mEditInputURL.setText(scanURL);
|
||||
startLivePusher(scanURL);
|
||||
}
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
mEditInputURL = findViewById(R.id.livepusher_et_input_url);
|
||||
mEditInputURL.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (actionId == EditorInfo.IME_ACTION_GO || (event != null && event.getAction() == KeyEvent.ACTION_UP)) {
|
||||
String url = mEditInputURL.getText().toString().trim();
|
||||
startLivePusher(url);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
findViewById(R.id.livepusher_ibtn_left).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
findViewById(R.id.livepusher_ibtn_right).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startQuestionLink();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
int id = view.getId();
|
||||
if (id == R.id.livepusher_btn_normal_url) {
|
||||
fetchPusherURL();
|
||||
} else if (id == R.id.livepusher_btn_qr_code_scan) {
|
||||
// Intent intent = new Intent(mContext, QRCodeScanActivity.class);
|
||||
// startActivityForResult(intent, ACTIVITY_SCAN_REQUEST_CODE);
|
||||
} else if (id == R.id.livepusher_btn_play) {
|
||||
String url = mEditInputURL.getText().toString().trim();
|
||||
startLivePusher(url);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchPusherURL() {
|
||||
|
||||
}
|
||||
|
||||
private void startLivePusher(String pushURL) {
|
||||
if (TextUtils.isEmpty(pushURL)) {
|
||||
Toast.makeText(mContext, getString(R.string.livepusher_input_push_url), Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
startLivePusher(pushURL, "", "", "", "");
|
||||
}
|
||||
}
|
||||
|
||||
private void startLivePusher(String pushURL, String rtmpPlayURL, String flvPlayURL, String hlsPlayURL, String realtimePlayURL) {
|
||||
|
||||
/*
|
||||
Intent intent = new Intent(mContext, CameraPushMainActivity.class);
|
||||
intent.putExtra(Constants.INTENT_URL_PUSH, pushURL);
|
||||
intent.putExtra(Constants.INTENT_URL_PLAY_RTMP, rtmpPlayURL);
|
||||
intent.putExtra(Constants.INTENT_URL_PLAY_FLV, flvPlayURL);
|
||||
intent.putExtra(Constants.INTENT_URL_PLAY_HLS, hlsPlayURL);
|
||||
intent.putExtra(Constants.INTENT_URL_PLAY_ACC, realtimePlayURL);
|
||||
startActivity(intent);
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
private void startQuestionLink() {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse(Constants.URL_PRODUCT_DOCUMENT));
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
59
app/src/main/java/net/spacen/xxh_video/Constants.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package net.spacen.xxh_video;
|
||||
|
||||
public class Constants {
|
||||
|
||||
public static final String URL_PRODUCT_DOCUMENT = "https://cloud.tencent.com/document/product/454/7885"; // 产品介绍链接
|
||||
public static final String URL_FETCH_PUSH_URL = "https://lvb.qcloud.com/weapp/utils/get_test_pushurl";
|
||||
|
||||
/**
|
||||
* QRCodeScanActivity完成扫描后,传递过来的结果的KEY
|
||||
*/
|
||||
public static final String INTENT_SCAN_RESULT = "SCAN_RESULT";
|
||||
|
||||
/**
|
||||
* LivePlayerURLActivity设置页面传递给LivePlayerActivity的直播地址
|
||||
*/
|
||||
public static final String INTENT_URL = "intent_url";
|
||||
|
||||
public static final String URL_PREFIX_HTTP = "http://";
|
||||
public static final String URL_PREFIX_HTTPS = "https://";
|
||||
public static final String URL_PREFIX_RTMP = "rtmp://";
|
||||
public static final String URL_SUFFIX_FLV = ".flv";
|
||||
public static final String URL_TX_SECRET = "txSecret";
|
||||
public static final String URL_BIZID = "bizid"; //是否为低延迟拉流地址
|
||||
|
||||
|
||||
public static final int ACTIVITY_TYPE_LIVE_PLAY = 1; // 标准直播播放
|
||||
public static final int ACTIVITY_TYPE_REALTIME_PLAY = 2; // 低延时直播播放
|
||||
|
||||
public static final float CACHE_TIME_FAST = 1.0f;
|
||||
public static final float CACHE_TIME_SMOOTH = 5.0f;
|
||||
|
||||
public static final int CACHE_STRATEGY_FAST = 0; //极速
|
||||
public static final int CACHE_STRATEGY_SMOOTH = 1; //流畅
|
||||
public static final int CACHE_STRATEGY_AUTO = 2; //自动
|
||||
|
||||
public static final int PLAY_STATUS_SUCCESS = 0;
|
||||
public static final int PLAY_STATUS_EMPTY_URL = -1;
|
||||
public static final int PLAY_STATUS_INVALID_URL = -2;
|
||||
public static final int PLAY_STATUS_INVALID_PLAY_TYPE = -3;
|
||||
public static final int PLAY_STATUS_INVALID_RTMP_URL = -4;
|
||||
public static final int PLAY_STATUS_INVALID_SECRET_RTMP_URL = -5;
|
||||
|
||||
/**
|
||||
* LivePlayerURLActivity设置页面传递给LivePlayerActivity的直播地址
|
||||
*/
|
||||
public static final String INTENT_URL_PUSH = "intent_url_push";
|
||||
public static final String INTENT_URL_PLAY_RTMP = "intent_url_play_rtmp";
|
||||
public static final String INTENT_URL_PLAY_FLV = "intent_url_play_flv";
|
||||
public static final String INTENT_URL_PLAY_HLS = "intent_url_play_hls";
|
||||
public static final String INTENT_URL_PLAY_ACC = "intent_url_play_acc";
|
||||
public static final String INTENT_URL_PLAY_RTC = "intent_url_play_rtc";
|
||||
|
||||
public static final String URL_PUSH = "url_push"; // RTMP 推流地址
|
||||
public static final String URL_PLAY_RTMP = "url_play_rtmp"; // RTMP 播放地址
|
||||
public static final String URL_PLAY_FLV = "url_play_flv"; // FLA 播放地址
|
||||
public static final String URL_PLAY_HLS = "url_play_hls"; // HLS 播放地址
|
||||
public static final String URL_PLAY_ACC = "url_play_acc"; // RTMP 加速流地址
|
||||
|
||||
}
|
||||
@@ -1,16 +1,28 @@
|
||||
package net.spacen.xxh_video;
|
||||
|
||||
import static com.tencent.live2.V2TXLiveCode.V2TXLIVE_ERROR_INVALID_PARAMETER;
|
||||
import static com.tencent.live2.V2TXLiveCode.V2TXLIVE_OK;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.VideoView;
|
||||
|
||||
@@ -18,6 +30,7 @@ import com.tencent.live2.V2TXLiveDef;
|
||||
import com.tencent.live2.V2TXLivePlayer;
|
||||
import com.tencent.live2.V2TXLivePlayerObserver;
|
||||
import com.tencent.live2.impl.V2TXLivePlayerImpl;
|
||||
import com.tencent.rtmp.TXLiveBase;
|
||||
import com.tencent.rtmp.TXLiveConstants;
|
||||
import com.tencent.rtmp.TXLivePlayer;
|
||||
import com.tencent.rtmp.ui.TXCloudVideoView;
|
||||
@@ -26,16 +39,42 @@ import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import tv.danmaku.ijk.media.player.IMediaPlayer;
|
||||
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
|
||||
|
||||
public final String TAG = MainActivity.class.getSimpleName();
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private ImageView mImageLoading; //显示视频缓冲动画
|
||||
private RelativeLayout mLayoutRoot; //视频暂停时更新背景
|
||||
private LinearLayout mLayoutToolbar; //视频Tools
|
||||
private RelativeLayout mliveplayer_title;
|
||||
|
||||
|
||||
|
||||
|
||||
private ImageView mImageRoot; //背景icon
|
||||
private ImageButton mButtonPlay; //视频的播放控制按钮
|
||||
private ImageButton mButtonRenderRotation; //调整视频播放方向:横屏、竖屏
|
||||
private ImageButton mButtonRenderMode; //调整视频渲染模式:全屏、自适应
|
||||
private ImageButton mButtonCacheStrategy; //设置视频的缓存策略
|
||||
private ImageView mImageCacheStrategyShadow;
|
||||
private ImageButton mImageLogInfo;
|
||||
|
||||
|
||||
//private RadioSelectView mLayoutCacheStrategy; //显示所有缓存模式的View
|
||||
//private LogInfoWindow mLogInfoWindow;
|
||||
|
||||
private int mLogClickCount = 0;
|
||||
|
||||
private V2TXLivePlayer mLivePlayer; //直播拉流的视频播放器
|
||||
private TXCloudVideoView mVideoView;
|
||||
|
||||
@@ -50,6 +89,12 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private OkHttpClient mOkHttpClient = null; //获取超低时延视频源直播地址
|
||||
|
||||
private int mCacheStrategy = Constants.CACHE_STRATEGY_AUTO; //Player缓存策略
|
||||
private int mActivityPlayType = Constants.ACTIVITY_TYPE_LIVE_PLAY; //播放类型
|
||||
private V2TXLiveDef.V2TXLiveFillMode mRenderMode = V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFit; //Player 当前渲染模式
|
||||
private V2TXLiveDef.V2TXLiveRotation mRenderRotation = V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation0; //Player 当前渲染角度
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -63,36 +108,135 @@ public class MainActivity extends AppCompatActivity {
|
||||
MyMqttService.startService(this); //开启服务
|
||||
|
||||
|
||||
//timer.schedule(task,0,10000);
|
||||
|
||||
|
||||
String licenceURL = "https://license.vod2.myqcloud.com/license/v2/1304883579_1/v_cube.license"; // 获取到的 licence url
|
||||
String licenceKey = "cd83b2d9f0570e9ab4b5059a3cf5ba36"; // 获取到的 licence key
|
||||
TXLiveBase.getInstance().setLicence(this, licenceURL, licenceKey);
|
||||
|
||||
|
||||
EventBus.getDefault().register(this);
|
||||
|
||||
mContext = this;
|
||||
|
||||
TextView t1 = (TextView) findViewById(R.id.liveplayer_title_textview);
|
||||
t1.setText(getAndroidID());
|
||||
|
||||
Toast.makeText(this, getAndroidID() + " 哈哈,我成功启动了!", Toast.LENGTH_LONG).show();
|
||||
Log.e("AutoRun","哈哈,我成功启动了!");
|
||||
|
||||
mPlayURL = "rtmp://v.dl8.tv/show/mini";
|
||||
|
||||
//mPlayerView 即 step1 中添加的界面 view
|
||||
mVideoView = (TXCloudVideoView) findViewById(R.id.video_view);
|
||||
vv_view = (VideoView) findViewById(R.id.vv_view);
|
||||
vv_view.setVisibility(View.GONE);
|
||||
initialize();
|
||||
}
|
||||
|
||||
mContext = this;
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
showToolbox();
|
||||
}
|
||||
|
||||
private void hideToolbox() {
|
||||
mLayoutToolbar.setVisibility(View.GONE);
|
||||
mliveplayer_title.setVisibility(View.GONE);
|
||||
}
|
||||
private void showToolbox() {
|
||||
|
||||
mLayoutToolbar.setVisibility(View.VISIBLE);
|
||||
mliveplayer_title.setVisibility(View.VISIBLE);
|
||||
|
||||
mLayoutToolbar.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hideToolbox();
|
||||
}},10000);
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
mLayoutRoot = (RelativeLayout) findViewById(R.id.liveplayer_rl_root);
|
||||
mliveplayer_title = (RelativeLayout) findViewById(R.id.liveplayer_title);
|
||||
|
||||
mImageRoot = (ImageView) findViewById(R.id.liveplayer_iv_root);
|
||||
|
||||
mLayoutToolbar = (LinearLayout) findViewById(R.id.liveplayer_ll_menu_layout);
|
||||
|
||||
|
||||
initPlayView();
|
||||
initPlayButton();
|
||||
initRenderRotationButton();
|
||||
initRenderModeButton();
|
||||
initCacheStrategyButton();
|
||||
//initNavigationBack();
|
||||
//initRTMPURL();
|
||||
|
||||
showToolbox();
|
||||
// 初始化完成之后自动播放
|
||||
startPlay();
|
||||
}
|
||||
|
||||
private void initPlayView() {
|
||||
mVideoView = (TXCloudVideoView) findViewById(R.id.video_view);
|
||||
mVideoView.setLogMargin(12, 12, 110, 60);
|
||||
mVideoView.showLog(false);
|
||||
|
||||
mVideoView.setOnClickListener(this);
|
||||
vv_view.setOnClickListener(this);
|
||||
|
||||
//创建 player 对象
|
||||
mLivePlayer = new V2TXLivePlayerImpl(mContext);
|
||||
mImageLoading = (ImageView) findViewById(R.id.liveplayer_iv_loading);
|
||||
}
|
||||
|
||||
//关键 player 对象与界面 view
|
||||
mLivePlayer.setRenderView(mVideoView);
|
||||
private void initCacheStrategyButton() {
|
||||
|
||||
String flvUrl = "rtmp://v.dl8.tv/show/mini";
|
||||
//mLayoutCacheStrategy = (RadioSelectView) findViewById(R.id.liveplayer_rsv_cache_strategy);
|
||||
mImageCacheStrategyShadow = (ImageView) findViewById(R.id.liveplayer_btn_cache_strategy_shadow);
|
||||
mButtonCacheStrategy = (ImageButton) findViewById(R.id.liveplayer_btn_cache_strategy);
|
||||
mButtonCacheStrategy.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(mContext, CameraPushEntranceActivity.class);
|
||||
/*
|
||||
intent.putExtra(Constants.INTENT_URL_PUSH, pushURL);
|
||||
intent.putExtra(Constants.INTENT_URL_PLAY_RTMP, rtmpPlayURL);
|
||||
intent.putExtra(Constants.INTENT_URL_PLAY_FLV, flvPlayURL);
|
||||
intent.putExtra(Constants.INTENT_URL_PLAY_HLS, hlsPlayURL);
|
||||
intent.putExtra(Constants.INTENT_URL_PLAY_ACC, realtimePlayURL);
|
||||
*/
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//自动模式
|
||||
mLivePlayer.setCacheParams(1.0f, 5.0f);
|
||||
private void startPlay() {
|
||||
String playURL = mPlayURL;
|
||||
int code = checkPlayURL(playURL);
|
||||
if (code != Constants.PLAY_STATUS_SUCCESS) {
|
||||
mIsPlaying = false;
|
||||
} else {
|
||||
mLivePlayer.setRenderView(mVideoView);
|
||||
mLivePlayer.setObserver(new MyPlayerObserver());
|
||||
|
||||
//极速模式
|
||||
//mLivePlayer.setCacheParams(1.0f, 1.0f);
|
||||
mLivePlayer.setRenderRotation(mRenderRotation);
|
||||
mLivePlayer.setRenderFillMode(mRenderMode);
|
||||
|
||||
//流畅模式
|
||||
//mLivePlayer.setCacheParams(5.0f, 5.0f);
|
||||
//设置完成之后再启动播放
|
||||
mLivePlayer.setCacheParams(1.0f, 5.0f);
|
||||
|
||||
mLivePlayer.startPlay(flvUrl);
|
||||
/**
|
||||
* result返回值:
|
||||
* 0 V2TXLIVE_OK; -2 V2TXLIVE_ERROR_INVALID_PARAMETER; -3 V2TXLIVE_ERROR_REFUSED;
|
||||
*/
|
||||
code = mLivePlayer.startPlay(playURL);
|
||||
mIsPlaying = code == 0;
|
||||
|
||||
Log.d("video render", "timetrack start play");
|
||||
}
|
||||
|
||||
//处理UI相关操作
|
||||
onPlayStart(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,6 +251,20 @@ public class MainActivity extends AppCompatActivity {
|
||||
destroy();
|
||||
}
|
||||
|
||||
private void startLoadingAnimation() {
|
||||
if (mImageLoading != null) {
|
||||
mImageLoading.setVisibility(View.VISIBLE);
|
||||
((AnimationDrawable) mImageLoading.getDrawable()).start();
|
||||
}
|
||||
}
|
||||
|
||||
private void stopLoadingAnimation() {
|
||||
if (mImageLoading != null) {
|
||||
mImageLoading.setVisibility(View.GONE);
|
||||
((AnimationDrawable) mImageLoading.getDrawable()).stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void stopPlay() {
|
||||
if (!mIsPlaying) {
|
||||
return;
|
||||
@@ -137,11 +295,11 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
public void onPlayStop() {
|
||||
|
||||
// mButtonPlay.setBackgroundResource(R.drawable.liveplayer_play_start_btn);
|
||||
// mLayoutRoot.setBackgroundResource(R.drawable.liveplayer_content_bg);
|
||||
// mImageRoot.setVisibility(View.VISIBLE);
|
||||
mButtonPlay.setBackgroundResource(R.drawable.liveplayer_play_start_btn);
|
||||
mLayoutRoot.setBackgroundResource(R.drawable.liveplayer_content_bg);
|
||||
mImageRoot.setVisibility(View.VISIBLE);
|
||||
// mLogInfoWindow.clear();
|
||||
// stopLoadingAnimation();
|
||||
stopLoadingAnimation();
|
||||
}
|
||||
|
||||
private class MyPlayerObserver extends V2TXLivePlayerObserver {
|
||||
@@ -235,6 +393,150 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int checkPlayURL(final String playURL) {
|
||||
if (TextUtils.isEmpty(playURL)) {
|
||||
return Constants.PLAY_STATUS_EMPTY_URL;
|
||||
}
|
||||
|
||||
if (!playURL.startsWith(Constants.URL_PREFIX_HTTP) && !playURL.startsWith(Constants.URL_PREFIX_HTTPS)
|
||||
&& !playURL.startsWith(Constants.URL_PREFIX_RTMP) && !playURL.startsWith("/")) {
|
||||
return Constants.PLAY_STATUS_INVALID_URL;
|
||||
}
|
||||
|
||||
boolean isLiveRTMP = playURL.startsWith(Constants.URL_PREFIX_RTMP);
|
||||
boolean isLiveFLV = (playURL.startsWith(Constants.URL_PREFIX_HTTP) || playURL.startsWith(Constants.URL_PREFIX_HTTPS)) && playURL.contains(Constants.URL_SUFFIX_FLV);
|
||||
|
||||
if (mActivityPlayType == Constants.ACTIVITY_TYPE_LIVE_PLAY) {
|
||||
if (isLiveRTMP) {
|
||||
return Constants.PLAY_STATUS_SUCCESS;
|
||||
}
|
||||
if (isLiveFLV) {
|
||||
return Constants.PLAY_STATUS_SUCCESS;
|
||||
}
|
||||
return Constants.PLAY_STATUS_INVALID_URL;
|
||||
}
|
||||
|
||||
if (mActivityPlayType == Constants.ACTIVITY_TYPE_REALTIME_PLAY) {
|
||||
if (!isLiveRTMP) {
|
||||
return Constants.PLAY_STATUS_INVALID_RTMP_URL;
|
||||
}
|
||||
if (!playURL.contains(Constants.URL_TX_SECRET)) {
|
||||
return Constants.PLAY_STATUS_INVALID_SECRET_RTMP_URL;
|
||||
}
|
||||
return Constants.PLAY_STATUS_SUCCESS;
|
||||
}
|
||||
return Constants.PLAY_STATUS_INVALID_URL;
|
||||
}
|
||||
|
||||
private void togglePlay() {
|
||||
Log.d(TAG, "togglePlay: mIsPlaying:" + mIsPlaying + ", mCurrentPlayType:" + mActivityPlayType);
|
||||
if (mIsPlaying) {
|
||||
stopPlay();
|
||||
} else {
|
||||
startPlay();
|
||||
}
|
||||
}
|
||||
|
||||
public void onPlayStart(int code) {
|
||||
|
||||
/*
|
||||
switch (code) {
|
||||
case V2TXLIVE_OK:
|
||||
startLoadingAnimation();
|
||||
break;
|
||||
case V2TXLIVE_ERROR_INVALID_PARAMETER:
|
||||
Toast.makeText(mContext, R.string.liveplayer_warning_res_url_invalid, Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (code != V2TXLIVE_OK) {
|
||||
mButtonPlay.setBackgroundResource(R.drawable.liveplayer_play_start_btn);
|
||||
mLayoutRoot.setBackgroundResource(R.drawable.liveplayer_content_bg);
|
||||
mImageRoot.setVisibility(View.VISIBLE);
|
||||
Bundle params = new Bundle();
|
||||
params.putString(TXLiveConstants.EVT_DESCRIPTION, mContext.getResources().getString(R.string.liveplayer_warning_checkout_res_url));
|
||||
mLogInfoWindow.setLogText(null, params, LogInfoWindow.CHECK_RTMP_URL_FAIL);
|
||||
} else {
|
||||
mButtonPlay.setBackgroundResource(R.drawable.liveplayer_play_pause_btn);
|
||||
mLayoutRoot.setBackgroundColor(getResources().getColor(R.color.liveplayer_black));
|
||||
mImageRoot.setVisibility(View.GONE);
|
||||
Bundle params = new Bundle();
|
||||
params.putString(TXLiveConstants.EVT_DESCRIPTION, mContext.getResources().getString(R.string.liveplayer_warning_checkout_res_url));
|
||||
mLogInfoWindow.setLogText(null, params, LogInfoWindow.CHECK_RTMP_URL_OK);
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
private void initPlayButton() {
|
||||
mButtonPlay = (ImageButton) findViewById(R.id.liveplayer_btn_play);
|
||||
mButtonPlay.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
togglePlay();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initRenderRotationButton() {
|
||||
mButtonRenderRotation = (ImageButton) findViewById(R.id.liveplayer_btn_render_rotate_landscape);
|
||||
mButtonRenderRotation.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
V2TXLiveDef.V2TXLiveRotation renderRotation = getRenderRotation();
|
||||
if (renderRotation == V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation0) {
|
||||
mButtonRenderRotation.setBackgroundResource(R.drawable.liveplayer_render_rotate_portrait);
|
||||
renderRotation = V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation270;
|
||||
} else if (renderRotation == V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation270) {
|
||||
mButtonRenderRotation.setBackgroundResource(R.drawable.liveplayer_render_rotate_landscape);
|
||||
renderRotation = V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation0;
|
||||
}
|
||||
setRenderRotation(renderRotation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setRenderMode(V2TXLiveDef.V2TXLiveFillMode renderMode) {
|
||||
mRenderMode = renderMode;
|
||||
mLivePlayer.setRenderFillMode(renderMode);
|
||||
}
|
||||
|
||||
private V2TXLiveDef.V2TXLiveFillMode getRenderMode() {
|
||||
return mRenderMode;
|
||||
}
|
||||
|
||||
private void setRenderRotation(V2TXLiveDef.V2TXLiveRotation renderRotation) {
|
||||
mRenderRotation = renderRotation;
|
||||
mLivePlayer.setRenderRotation(renderRotation);
|
||||
}
|
||||
private V2TXLiveDef.V2TXLiveRotation getRenderRotation() {
|
||||
return mRenderRotation;
|
||||
}
|
||||
|
||||
|
||||
private void initRenderModeButton() {
|
||||
mButtonRenderMode = (ImageButton) findViewById(R.id.liveplayer_btn_render_mode_fill);
|
||||
mButtonRenderMode.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
V2TXLiveDef.V2TXLiveFillMode renderMode = getRenderMode();
|
||||
if (getRenderMode() == V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFill) {
|
||||
mButtonRenderMode.setBackgroundResource(R.drawable.liveplayer_render_mode_fill);
|
||||
renderMode = V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFit;
|
||||
} else if (getRenderMode() == V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFit) {
|
||||
mButtonRenderMode.setBackgroundResource(R.drawable.liveplayer_adjust_mode_btn);
|
||||
renderMode = V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFill;
|
||||
}
|
||||
setRenderMode(renderMode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private String getAndroidID() {
|
||||
|
||||
return Settings.Secure.getString( getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
@@ -243,15 +545,15 @@ public class MainActivity extends AppCompatActivity {
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onGetMessage(MessageWrap message) {
|
||||
// getBinding().tvMessage.setText(message.message);
|
||||
Log.i(TAG, "收到消息: " + new String(message.message));
|
||||
Toast.makeText(getApplicationContext(), "EventBus: " + new String(message.message), Toast.LENGTH_LONG).show();
|
||||
// Log.i(TAG, "收到消息: " + new String(message.message));
|
||||
// Toast.makeText(getApplicationContext(), "EventBus: " + new String(message.message), Toast.LENGTH_LONG).show();
|
||||
|
||||
String url = new String(message.message);
|
||||
|
||||
if (url.substring(url.length()-4).equals("m3u8")){
|
||||
mLivePlayer.stopPlay();
|
||||
mVideoView.setVisibility(View.GONE);
|
||||
|
||||
|
||||
vv_view.setVisibility(View.VISIBLE);
|
||||
vv_view.setVideoPath(url);
|
||||
vv_view.start();
|
||||
|
||||
@@ -37,11 +37,11 @@ public class MyMqttService extends Service {
|
||||
|
||||
private static MqttAndroidClient mqttAndroidClient;
|
||||
private MqttConnectOptions mMqttConnectOptions;
|
||||
public String HOST = "tcp://mqtt.hulian100.cn:1883";//服务器地址(协议+地址+端口号)
|
||||
public String HOST = "tcp://red.xinxinghang.cn:1883";//服务器地址(协议+地址+端口号)
|
||||
public String USERNAME = "admin";//用户名
|
||||
public String PASSWORD = "password";//密码
|
||||
public static String PUBLISH_TOPIC = "/xxh/rtmp-video/";//发布主题
|
||||
public static String RESPONSE_TOPIC = "/xxh/rtmp-video/";//响应主题
|
||||
public static String PUBLISH_TOPIC = "/xxh/video/reg";//发布主题
|
||||
public static String RESPONSE_TOPIC = "/xxh/video/";//订阅主题
|
||||
|
||||
public static String CLIENTID = "";
|
||||
|
||||
@@ -68,6 +68,8 @@ public class MyMqttService extends Service {
|
||||
mContext.startService(new Intent(mContext, MyMqttService.class));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 发布 (模拟其他客户端发布消息)
|
||||
*
|
||||
@@ -85,6 +87,24 @@ public class MyMqttService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发布 (模拟其他客户端发布消息)
|
||||
*
|
||||
* @param message 消息
|
||||
*/
|
||||
public static void publish(String Topic,String message) {
|
||||
String topic = PUBLISH_TOPIC;
|
||||
Integer qos = 2;
|
||||
Boolean retained = false;
|
||||
try {
|
||||
//参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
|
||||
mqttAndroidClient.publish(Topic, message.getBytes(), qos.intValue(), retained.booleanValue());
|
||||
} catch (MqttException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应 (收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等)
|
||||
*
|
||||
@@ -179,8 +199,16 @@ public class MyMqttService extends Service {
|
||||
@Override
|
||||
public void onSuccess(IMqttToken arg0) {
|
||||
Log.i(TAG, "连接成功 ");
|
||||
|
||||
Integer qos = 2;
|
||||
Boolean retained = false;
|
||||
|
||||
try {
|
||||
mqttAndroidClient.subscribe(PUBLISH_TOPIC + CLIENTID, 2);//订阅主题,参数:主题、服务质量
|
||||
String message = "{\"terminal_uid\":\"" + CLIENTID + "\"}";
|
||||
|
||||
mqttAndroidClient.publish(PUBLISH_TOPIC, message.getBytes(), qos.intValue(), retained.booleanValue());
|
||||
|
||||
mqttAndroidClient.subscribe(RESPONSE_TOPIC + CLIENTID, 2);//订阅主题,参数:主题、服务质量
|
||||
} catch (MqttException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
BIN
app/src/main/res/drawable-xhdpi/liveplayer_acc.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_adjust_mode_btn.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_bg_icon.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_cache_strategy.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_decode_btn.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_ic_qcode.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_log_info_btn_show.png
Normal file
|
After Width: | Height: | Size: 911 B |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_loginfo.9.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_play_pause_btn.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_play_start_btn.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_radio_btn_checked.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/drawable-xhdpi/liveplayer_render_mode_fill.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_bg_icon.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_bgm.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_camera_back_btn.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_camera_front.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_copy.png
Normal file
|
After Width: | Height: | Size: 190 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_ic_green.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_ic_net_speed0.png
Normal file
|
After Width: | Height: | Size: 915 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_ic_net_speed1.png
Normal file
|
After Width: | Height: | Size: 915 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_ic_net_speed2.png
Normal file
|
After Width: | Height: | Size: 897 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_ic_net_speed3.png
Normal file
|
After Width: | Height: | Size: 870 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_ic_net_speed4.png
Normal file
|
After Width: | Height: | Size: 852 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_ic_net_speed5.png
Normal file
|
After Width: | Height: | Size: 804 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_ic_qcode.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_ic_red.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_loading_image0.png
Normal file
|
After Width: | Height: | Size: 808 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_loading_image1.png
Normal file
|
After Width: | Height: | Size: 858 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_loading_image2.png
Normal file
|
After Width: | Height: | Size: 881 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_loading_image3.png
Normal file
|
After Width: | Height: | Size: 848 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_loading_image4.png
Normal file
|
After Width: | Height: | Size: 843 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_loading_image5.png
Normal file
|
After Width: | Height: | Size: 834 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_loading_image6.png
Normal file
|
After Width: | Height: | Size: 780 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_loading_image7.png
Normal file
|
After Width: | Height: | Size: 862 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_loginfo.png
Normal file
|
After Width: | Height: | Size: 846 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_lvb_beauty.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_more.png
Normal file
|
After Width: | Height: | Size: 659 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_pause.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_pause_publish.jpg
Normal file
|
After Width: | Height: | Size: 145 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_qr_code_btn.png
Normal file
|
After Width: | Height: | Size: 269 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_radio_btn_checked.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_role.png
Normal file
|
After Width: | Height: | Size: 877 B |
BIN
app/src/main/res/drawable-xhdpi/livepusher_start.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/livepusher_watermark.png
Executable file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_bg_icon.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
5
app/src/main/res/drawable-xxhdpi/liveplayer_btn_bg.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="3dp" />
|
||||
<solid android:color="#ff0062e3" />
|
||||
</shape>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="135"
|
||||
android:endColor="#FF13294B"
|
||||
android:startColor="#FF000000" />
|
||||
</shape>
|
||||
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_ic_back.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_ic_net_speed0.png
Normal file
|
After Width: | Height: | Size: 915 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_ic_net_speed1.png
Normal file
|
After Width: | Height: | Size: 915 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_ic_net_speed2.png
Normal file
|
After Width: | Height: | Size: 897 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_ic_net_speed3.png
Normal file
|
After Width: | Height: | Size: 870 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_ic_net_speed4.png
Normal file
|
After Width: | Height: | Size: 852 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_ic_net_speed5.png
Normal file
|
After Width: | Height: | Size: 804 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_ic_question_link.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_ic_slider.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,11 @@
|
||||
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
|
||||
|
||||
<item android:drawable="@drawable/liveplayer_loading_image0" android:duration="100"></item>
|
||||
<item android:drawable="@drawable/liveplayer_loading_image1" android:duration="100"></item>
|
||||
<item android:drawable="@drawable/liveplayer_loading_image2" android:duration="100"></item>
|
||||
<item android:drawable="@drawable/liveplayer_loading_image3" android:duration="100"></item>
|
||||
<item android:drawable="@drawable/liveplayer_loading_image4" android:duration="100"></item>
|
||||
<item android:drawable="@drawable/liveplayer_loading_image5" android:duration="100"></item>
|
||||
<item android:drawable="@drawable/liveplayer_loading_image6" android:duration="100"></item>
|
||||
<item android:drawable="@drawable/liveplayer_loading_image7" android:duration="100"></item>
|
||||
</animation-list>
|
||||
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_loading_image0.png
Normal file
|
After Width: | Height: | Size: 808 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_loading_image1.png
Normal file
|
After Width: | Height: | Size: 858 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_loading_image2.png
Normal file
|
After Width: | Height: | Size: 881 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_loading_image3.png
Normal file
|
After Width: | Height: | Size: 848 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_loading_image4.png
Normal file
|
After Width: | Height: | Size: 843 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_loading_image5.png
Normal file
|
After Width: | Height: | Size: 834 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_loading_image6.png
Normal file
|
After Width: | Height: | Size: 780 B |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_loading_image7.png
Normal file
|
After Width: | Height: | Size: 862 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/drawable-xxhdpi/liveplayer_question_link.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
5
app/src/main/res/drawable-xxhdpi/livepusher_btn_bg.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="3dp" />
|
||||
<solid android:color="#ff0062e3" />
|
||||
</shape>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="135"
|
||||
android:endColor="#FF13294B"
|
||||
android:startColor="#FF000000" />
|
||||
</shape>
|
||||
BIN
app/src/main/res/drawable-xxhdpi/livepusher_ic_back.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
8
app/src/main/res/drawable-xxhdpi/livepusher_input_bg.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<corners android:radius="3dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#ff0062e3" />
|
||||
</shape>
|
||||
BIN
app/src/main/res/drawable-xxhdpi/livepusher_question_link.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
@@ -1,11 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout 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/liveplayer_rl_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/liveplayer_content_bg"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/liveplayer_iv_root"
|
||||
android:layout_width="116dp"
|
||||
android:layout_height="112dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@drawable/liveplayer_bg_icon"/>
|
||||
|
||||
<com.tencent.rtmp.ui.TXCloudVideoView
|
||||
android:id="@+id/video_view"
|
||||
android:layout_width="match_parent"
|
||||
@@ -20,5 +29,94 @@
|
||||
android:layout_centerInParent="true"
|
||||
android:visibility="visible" />
|
||||
|
||||
<include
|
||||
layout="@layout/liveplayer_top_bar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="18dp"
|
||||
android:layout_marginRight="18dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/liveplayer_ll_menu_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/liveplayer_btn_play"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/liveplayer_play_start_btn"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/liveplayer_btn_render_rotate_landscape"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/liveplayer_render_rotate_landscape"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/liveplayer_btn_render_mode_fill"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/liveplayer_render_mode_fill"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/liveplayer_btn_cache_strategy"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/liveplayer_cache_strategy"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/liveplayer_btn_cache_strategy_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#cc000000"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/liveplayer_iv_loading"
|
||||
android:layout_width="34dp"
|
||||
android:layout_height="34dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@drawable/liveplayer_loading_animation"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
40
app/src/main/res/layout/liveplayer_top_bar_layout.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/liveplayer_title">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/liveplayer_ibtn_left"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:paddingTop="17dp"
|
||||
android:paddingRight="17dp"
|
||||
android:paddingBottom="17dp"
|
||||
android:src="@drawable/liveplayer_ic_back" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/liveplayer_title_textview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="2dp"
|
||||
android:text="@string/liveplayer_title_live_player"
|
||||
android:textColor="@color/liveplayer_white"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/liveplayer_ibtn_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:paddingLeft="17dp"
|
||||
android:paddingTop="17dp"
|
||||
android:paddingBottom="17dp"
|
||||
android:src="@drawable/liveplayer_ic_question_link" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/livepusher_content_bg"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="18dp"
|
||||
android:paddingRight="18dp">
|
||||
|
||||
<include
|
||||
layout="@layout/livepusher_top_bar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="@string/livepusher_play_hint"
|
||||
android:textColor="@color/livepusher_white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/livepusher_play_hint_1"
|
||||
android:textColor="#FF6B82A8"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="@string/livepusher_play_hint_2"
|
||||
android:textColor="#FF6B82A8"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/livepusher_btn_normal_url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="@drawable/livepusher_btn_bg"
|
||||
android:gravity="center"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/livepusher_auto_fetch_url"
|
||||
android:textColor="@color/livepusher_white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:background="#FF122755" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="@string/livepusher_have_push_url"
|
||||
android:textColor="#FF6B82A8"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/livepusher_et_input_url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="@drawable/livepusher_input_bg"
|
||||
android:hint="@string/livepusher_input_push_url"
|
||||
android:imeOptions="actionGo"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/livepusher_white"
|
||||
android:textColorHint="#FF6B82A8" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="20dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/livepusher_btn_qr_code_scan"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/livepusher_btn_bg"
|
||||
android:gravity="center"
|
||||
android:onClick="onClick"
|
||||
android:textColor="@color/livepusher_white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="@drawable/livepusher_ic_qcode" />
|
||||
</RelativeLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/livepusher_btn_play"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="@drawable/livepusher_btn_bg"
|
||||
android:gravity="center"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/livepusher_start_push"
|
||||
android:textColor="@color/livepusher_white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
39
app/src/main/res/layout/livepusher_top_bar_layout.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/livepusher_ibtn_left"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:paddingTop="17dp"
|
||||
android:paddingRight="17dp"
|
||||
android:paddingBottom="17dp"
|
||||
android:src="@drawable/livepusher_ic_back" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/livepusher_title_textview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="2dp"
|
||||
android:text="@string/livepusher_camera_push"
|
||||
android:textColor="@color/livepusher_white"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/livepusher_ibtn_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:paddingLeft="17dp"
|
||||
android:paddingTop="17dp"
|
||||
android:paddingBottom="17dp"
|
||||
android:src="@drawable/livepusher_question_link" />
|
||||
|
||||
</RelativeLayout>
|
||||
29
app/src/main/res/values/arrays.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- 画质偏好列表 -->
|
||||
<string-array name="livepusher_video_quality_list">
|
||||
<item>蓝光</item>
|
||||
<item>超清</item>
|
||||
<item>高清</item>
|
||||
<item>标清</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="livepusher_voice_channel">
|
||||
<item>语音</item>
|
||||
<item>标准</item>
|
||||
<item>音乐</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="livepusher_setting">
|
||||
<item>带宽适应</item>
|
||||
<item>耳返</item>
|
||||
<item>静音模式</item>
|
||||
<item>横屏推流</item>
|
||||
<item>图像水印</item>
|
||||
<item>观看端镜像</item>
|
||||
<item>后置闪光灯</item>
|
||||
<item>手动点击曝光对焦</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
@@ -7,4 +7,31 @@
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
<color name="liveplayer_color_accent">#0accac</color>
|
||||
<color name="liveplayer_transparent">#00000000</color>
|
||||
<color name="liveplayer_red">#FF3333</color>
|
||||
<color name="liveplayer_white">#FFFFFF</color>
|
||||
<color name="liveplayer_black">#000000</color>
|
||||
<color name="liveplayer_gray">#787878</color>
|
||||
<color name="liveplayer_background_gray">#EBEBEB</color>
|
||||
<color name="liveplayer_color_primary_dark">#21a3f5</color>
|
||||
<color name="liveplayer_hint_color">#777777</color>
|
||||
<color name="liveplayer_dim_gray">#696969</color>
|
||||
<color name="liveplayer_text_gray">#FF6B82A8</color>
|
||||
|
||||
<color name="livepusher_accent">#0ACCAC</color>
|
||||
<color name="livepusher_red">#FF3333</color>
|
||||
<color name="livepusher_white">#FFFFFF</color>
|
||||
<color name="livepusher_black">#000000</color>
|
||||
<color name="livepusher_hlf_transparent">#30000000</color>
|
||||
<color name="livepusher_btn_line">#BBBBBB</color>
|
||||
<color name="livepusher_gray_white">#EEEEEE</color>
|
||||
<color name="livepusher_green">#33DA33</color>
|
||||
<color name="livepusher_dark_gray">#3F000000</color>
|
||||
<color name="livepusher_light_gray">#EDEDEF</color>
|
||||
<color name="livepusher_gray">#666666</color>
|
||||
<color name="livepusher_audio_gray">#CC000000</color>
|
||||
<color name="livepusher_text_gray">#FF6B82A8</color>
|
||||
<color name="livepusher_blue">#FF0062E3</color>
|
||||
|
||||
</resources>
|
||||
@@ -48,4 +48,69 @@
|
||||
<string name="liveplayer_start_realtime_paly">低延时播放</string>
|
||||
<string name="liveplayer_not_realtime_url">请输入低延时播放地址</string>
|
||||
<string name="liveplayer_camera">请先打开摄像头权限</string>
|
||||
|
||||
<string name="livepusher_camera_push">摄像头推流</string>
|
||||
<string name="livepusher_close">关闭</string>
|
||||
<string name="livepusher_coding_rate">编码码率</string>
|
||||
<string name="livepusher_upload_speed">上传网速</string>
|
||||
<string name="livepusher_model">机型</string>
|
||||
<string name="livepusher_version">Android系统版本</string>
|
||||
<string name="livepusher_fps">FPS</string>
|
||||
<string name="livepusher_gop">GOP</string>
|
||||
<string name="livepusher_step1">阶段一</string>
|
||||
<string name="livepusher_step1_value">检查地址合法性</string>
|
||||
<string name="livepusher_step2">阶段二</string>
|
||||
<string name="livepusher_step2_value">连接到云服务器</string>
|
||||
<string name="livepusher_step3">阶段三</string>
|
||||
<string name="livepusher_step3_value">摄像头打开成功</string>
|
||||
<string name="livepusher_step4">阶段四</string>
|
||||
<string name="livepusher_step4_value">编码器正常启动</string>
|
||||
<string name="livepusher_step5">阶段五</string>
|
||||
<string name="livepusher_step5_value">开始进入推流中...</string>
|
||||
<string name="livepusher_hardcode">编码器正常启动[硬编]</string>
|
||||
<string name="livepusher_softcode">编码器正常启动[软编]</string>
|
||||
<string name="livepusher_input_push_url">请输入推流地址</string>
|
||||
<string name="livepusher_check_url">检查地址合法性</string>
|
||||
<string name="livepusher_url_illegal">推流地址不合法,目前支持rtmp推流!</string>
|
||||
<string name="livepusher_license_check_fail">License 校验失败</string>
|
||||
<string name="livepusher_license_click_info"> 详情请点击[</string>
|
||||
<string name="livepusher_license_click_use_info"> 详情请点击[License 使用指南</string>
|
||||
<string name="livepusher_push_fail">推流失败</string>
|
||||
<string name="livepusher_comfirm">确定</string>
|
||||
<string name="livepusher_send">发送</string>
|
||||
<string name="livepusher_receive_event">receive event: </string>
|
||||
<string name="livepusher_pushing_start_stop_retry_push">当前正在推流,启动或关闭缩放需要重新推流</string>
|
||||
<string name="livepusher_pushing_start_stop_retry_push_by_focus">当前正在推流,启动或关闭手动对焦需要重新推流</string>
|
||||
<string name="livepusher_screenshot_success">截图成功</string>
|
||||
<string name="livepusher_screenshot_fail">截图失败</string>
|
||||
<string name="livepusher_screenshot_fail_push">截图失败,请先发起推流</string>
|
||||
<string name="livepusher_share_pic">图片分享</string>
|
||||
<string name="livepusher_network_warning_hint">当前网络质量很糟糕,建议您拉近离路由器的距离,避免WiFi穿墙!</string>
|
||||
<string name="livepusher_local_snapshot">本地截图</string>
|
||||
<string name="livepusher_snapshot">截图</string>
|
||||
<string name="livepusher_send_message">发送消息</string>
|
||||
<string name="livepusher_empty_message">发送消息</string>
|
||||
<string name="livepusher_error_drop_frame">丢帧严重</string>
|
||||
<string name="livepusher_video_quality">画质</string>
|
||||
<string name="livepusher_audio_quality">音质选择</string>
|
||||
<string name="livepusher_primary_clip">已添加至剪切板</string>
|
||||
<string name="livepusher_realtime">低延时</string>
|
||||
<string name="livepusher_leb">快直播</string>
|
||||
<string name="livepusher_play_hint">你需要a,b两台手机进行测试</string>
|
||||
<string name="livepusher_play_hint_1">①a手机生成推流地址录制</string>
|
||||
<string name="livepusher_play_hint_2">②b手机输入推流地址或扫码拉流并播放测试</string>
|
||||
<string name="livepusher_auto_fetch_url">自动生成推流地址</string>
|
||||
<string name="livepusher_have_push_url">我有推流地址</string>
|
||||
<string name="livepusher_start_push">开始推流</string>
|
||||
<string name="livepusher_fetch_url">地址获取中</string>
|
||||
<string name="livepusher_play_url_generated_success">播放地址生成成功</string>
|
||||
<string name="livepusher_another_phone_scan_or_copy">用另外一台手机扫码或复制地址进行播放测试</string>
|
||||
<string name="livepusher_copy_play_url">复制直播地址</string>
|
||||
<string name="livepusher_setting">设置</string>
|
||||
<string name="livepusher_audio_quality_speech">语音</string>
|
||||
<string name="livepusher_audio_quality_default">标准</string>
|
||||
<string name="livepusher_audio_quality_music">音乐</string>
|
||||
<string name="livepusher_app_camera">请先打开摄像头权限</string>
|
||||
<string name="livepusher_app_camera_mic">请先打开摄像头和麦克风权限</string>
|
||||
|
||||
</resources>
|
||||
@@ -16,4 +16,18 @@
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
<style name="LivePusherMlvbDialogFragment" parent="@android:style/Theme.Holo.Dialog">
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowCloseOnTouchOutside">true</item>
|
||||
</style>
|
||||
|
||||
<style name="LivePusherRoomSettingDialog" parent="@android:style/Theme.Holo.Dialog">
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:windowCloseOnTouchOutside">true</item>
|
||||
</style>
|
||||
|
||||
|
||||
</resources>
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.spacen.xxh_video;
|
||||
package net.spacen.xxh-video;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||