This commit is contained in:
zhongjin
2021-11-27 21:04:16 +08:00
parent 42215dfa59
commit c36e1434e4
95 changed files with 1037 additions and 30 deletions

1
.idea/gradle.xml generated
View File

@@ -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
View File

@@ -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
View 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>

View File

@@ -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.+'

View File

@@ -1,4 +1,4 @@
package net.spacen.xxh_video;
package net.spacen.xxh-video;
import android.content.Context;

View File

@@ -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-->

View File

@@ -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);
}
}

View 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 加速流地址
}

View File

@@ -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();

View File

@@ -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();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View 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>

View File

@@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View 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>

View File

@@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -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>

View 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>

View File

@@ -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>

View 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>

View 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>

View File

@@ -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>

View File

@@ -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">你需要ab两台手机进行测试</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>

View File

@@ -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>

View File

@@ -1,4 +1,4 @@
package net.spacen.xxh_video;
package net.spacen.xxh-video;
import org.junit.Test;