Skip to content

Commit

Permalink
Merge pull request #327 from BoleLiu/dev
Browse files Browse the repository at this point in the history
Release v3.1.0
  • Loading branch information
BoleLiu authored May 12, 2021
2 parents 7d50a61 + f1dcc5d commit fa2f161
Show file tree
Hide file tree
Showing 79 changed files with 229 additions and 41 deletions.
12 changes: 9 additions & 3 deletions PLDroidMediaStreamingDemo/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ android {
applicationId "com.qiniu.pili.droid.streaming.demo"
minSdkVersion 18
targetSdkVersion 29
versionCode 72
versionName "3.0.2"
versionCode 73
versionName "3.1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}

dependencies {
Expand All @@ -35,6 +41,6 @@ dependencies {
implementation project(':library')
} else {
// 推流 SDK jar 包,为推流 SDK 必须依赖的库
implementation files('libs/pldroid-media-streaming-3.0.2.jar')
implementation files('libs/pldroid-media-streaming-3.1.0.jar')
}
}
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.zxing.integration.android.IntentResult;
import com.qiniu.pili.droid.streaming.PLAuthenticationResultCallback;
import com.qiniu.pili.droid.streaming.StreamingEnv;
import com.qiniu.pili.droid.streaming.common.FileLogHelper;
import com.qiniu.pili.droid.streaming.demo.activity.AVStreamingActivity;
import com.qiniu.pili.droid.streaming.demo.activity.AudioStreamingActivity;
import com.qiniu.pili.droid.streaming.demo.activity.ImportStreamingActivity;
Expand All @@ -35,7 +36,10 @@
import com.qiniu.pili.droid.streaming.demo.utils.PermissionChecker;
import com.qiniu.pili.droid.streaming.demo.utils.Util;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

public class MainActivity extends FragmentActivity {
Expand All @@ -56,7 +60,9 @@ public class MainActivity extends FragmentActivity {
private TextView mInputTextTV;
private Spinner mStreamTypeSpinner;
private CheckBox mDebugModeCheckBox;
private RadioButton mRtmpPushButton;
private RadioButton mQuicPushButton;
private RadioButton mSrtPushButton;

private EncodingConfigFragment mEncodingConfigFragment;
private CameraConfigFragment mCameraConfigFragment;
Expand All @@ -67,31 +73,58 @@ public class MainActivity extends FragmentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 开启日志的本地保存,保存在应用私有目录(getExternalFilesDir) 或者 getFilesDir 文件目录下的 Pili 文件夹中
StreamingEnv.setLogLevel(Log.INFO);
StreamingEnv.startLogFile();

TextView versionInfo = (TextView) findViewById(R.id.version_info);
mInputTextTV = (TextView) findViewById(R.id.input_url);
mStreamTypeSpinner = (Spinner) findViewById(R.id.stream_types);
mDebugModeCheckBox = (CheckBox) findViewById(R.id.debug_mode);
mRtmpPushButton = (RadioButton) findViewById(R.id.transfer_rtmp);
mQuicPushButton = (RadioButton) findViewById(R.id.transfer_quic);
mSrtPushButton = (RadioButton) findViewById(R.id.transfer_srt);

mInputTextTV.setText(Cache.retrieveURL(this));
String publishUrl = Cache.retrieveURL(this);
if (publishUrl.startsWith("srt")) {
mSrtPushButton.setChecked(true);
} else {
mRtmpPushButton.setChecked(true);
}
mInputTextTV.setText(publishUrl);

FragmentManager fragmentManager = getSupportFragmentManager();
mEncodingConfigFragment = (EncodingConfigFragment) fragmentManager.findFragmentById(R.id.encoding_config_fragment);
mCameraConfigFragment = (CameraConfigFragment) fragmentManager.findFragmentById(R.id.camera_config_fragment);

versionInfo.setText("versionName: " + BuildConfig.VERSION_NAME + " versionCode: " + BuildConfig.VERSION_CODE);
versionInfo.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
StreamingEnv.reportLogFiles(new FileLogHelper.LogReportCallback() {
@Override
public void onReportSuccess(List<String> logNames) {
if (logNames.size() == 0) {
return;
}
for (String logName : logNames) {
Log.i(TAG, logName);
}
Log.i(TAG, "日志已上传");
Toast.makeText(MainActivity.this, "日志已上传!", Toast.LENGTH_SHORT).show();
}

@Override
public void onReportError(String name, String errorMsg) {
Toast.makeText(MainActivity.this, "日志 " + name + " 上传失败: " + errorMsg, Toast.LENGTH_SHORT).show();
}
});
return true;
}
});
initStreamTypeSpinner();
}

@Override
protected void onDestroy() {
super.onDestroy();
StreamingEnv.stopLogFile();
Log.i(TAG, "Log file path : " + StreamingEnv.getLogFilePath());
}

@Override
Expand Down Expand Up @@ -129,17 +162,24 @@ public void launchStreaming(View v) {
Util.showToast(this, "推流地址不能为空!!!");
return;
}
if ((mSrtPushButton.isChecked() && !streamText.startsWith("srt"))
|| (!mSrtPushButton.isChecked() && !streamText.startsWith("rtmp"))) {
Util.showToast(this, "请检查推流地址和协议是否匹配!!!");
return;
}

if (mDebugModeCheckBox.isChecked()) {
StreamingEnv.setLogLevel(Log.VERBOSE);
}

boolean quicEnable = mQuicPushButton.isChecked();
boolean srtEnable = mSrtPushButton.isChecked();

int pos = mStreamTypeSpinner.getSelectedItemPosition();
Intent intent = new Intent(this, ACTIVITY_CLASSES[pos]);
intent.putExtra(Config.PUBLISH_URL, streamText);
intent.putExtra(Config.TRANSFER_MODE_QUIC, quicEnable);
intent.putExtra(Config.TRANSFER_MODE_SRT, srtEnable);
intent.putExtras(mEncodingConfigFragment.getIntent());
boolean isAudioStereo = ((CheckBox) findViewById(R.id.audio_channel_stereo)).isChecked();
intent.putExtra(Config.AUDIO_CHANNEL_STEREO, isAudioStereo);
Expand Down Expand Up @@ -182,6 +222,9 @@ public void onClickGenPublishURL(View v) {
@Override
public void run() {
String publishUrl = genPublishURL();
if (mSrtPushButton.isChecked() && publishUrl.startsWith("rtmp://")) {
publishUrl = getSrtPublishUrl(publishUrl);
}
if (publishUrl != null) {
Cache.saveURL(MainActivity.this, publishUrl);
updateInputTextView(publishUrl);
Expand Down Expand Up @@ -255,6 +298,35 @@ private String genPublishURL() {
return publishUrl;
}

/**
* 自定义组装 SRT 推流地址
*
* 建议由您业务服务端生成符合规范的 SRT 推流地址
* 地址规范可参考:https://github.com/Haivision/srt/blob/master/docs/features/access-control.md#general-syntax
*
* @param rtmpUrl rtmp 地址
* @return 组装的 SRT 地址
*/
private String getSrtPublishUrl(String rtmpUrl) {
URI u;
try {
u = new URI(rtmpUrl);
String path = u.getPath().substring(1);
String query = u.getQuery();
StringBuilder publishUrl = new StringBuilder(String.format("srt://%s?streamid=#!::h=%s,m=publish", u.getHost(), path));
if (query != null) {
String[] queries = query.split("&");
for (String q : queries) {
publishUrl.append(",").append(q);
}
}
return publishUrl.toString();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return "";
}

private void updateInputTextView(final String url) {
runOnUiThread(new Runnable() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.app.Application;
import android.content.Intent;
import android.util.Log;

import com.qiniu.pili.droid.streaming.StreamingEnv;
import com.qiniu.pili.droid.streaming.demo.service.KeepAppAliveService;
Expand All @@ -22,6 +23,11 @@ public void onCreate() {
* 注意:参数 userId 代表用户的唯一标识符,用于区分不同的用户
*/
StreamingEnv.init(getApplicationContext(), Util.getUserId(getApplicationContext()));
// 设置日志等级
StreamingEnv.setLogLevel(Log.INFO);
// 开启日志的本地保存,保存在应用私有目录(getExternalFilesDir) 或者 getFilesDir 文件目录下的 Pili 文件夹中
// 默认为关闭
StreamingEnv.setLogfileEnabled(true);

/**
* track app background state to avoid possibly stopping microphone recording
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public class AVStreamingActivity extends Activity implements

private String mPublishUrl;
private boolean mIsQuicEnabled;
private boolean mIsSrtEnabled;
private String mPicStreamingFilePath;

// 推流操作管理类实例
Expand Down Expand Up @@ -134,6 +135,7 @@ protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
mPublishUrl = intent.getStringExtra(Config.PUBLISH_URL);
mIsQuicEnabled = intent.getBooleanExtra(Config.TRANSFER_MODE_QUIC, false);
mIsSrtEnabled = intent.getBooleanExtra(Config.TRANSFER_MODE_SRT, false);
mAudioStereoEnable = intent.getBooleanExtra(Config.AUDIO_CHANNEL_STEREO, false);

HandlerThread handlerThread = new HandlerThread(TAG);
Expand Down Expand Up @@ -178,10 +180,12 @@ protected void onPause() {
protected void onStop() {
super.onStop();
// 如果当前正在图片推流,则退后台不会终止推流
if (!mIsPictureStreaming) {
if (isFinishing() || !mIsPictureStreaming) {
mIsReady = false;
if (mIsStreaming) {
Toast.makeText(this, "推流已停止!!!", Toast.LENGTH_SHORT).show();
}
mMediaStreamingManager.pause();
Toast.makeText(this, "推流已停止!!!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "当前正在图片推流!!!", Toast.LENGTH_SHORT).show();
}
Expand All @@ -192,6 +196,7 @@ protected void onDestroy() {
super.onDestroy();
if (mSubThreadHandler != null) {
mSubThreadHandler.getLooper().quit();
mSubThreadHandler = null;
}
// 销毁推流 Manager 的资源
mMediaStreamingManager.destroy();
Expand Down Expand Up @@ -239,6 +244,7 @@ private void initEncodingProfile() {
// 是否开启 QUIC 推流。
// QUIC 是基于 UDP 开发的可靠传输协议,在弱网下拥有更好的推流效果,相比于 TCP 拥有更低的延迟,可抵抗更高的丢包率。
mProfile.setQuicEnable(mIsQuicEnabled);
mProfile.setSrtEnabled(mIsSrtEnabled);

// 自定义配置音频的采样率、码率以及声道数的对象,如果使用预设配置,则无需实例化
StreamingProfile.AudioProfile aProfile = null;
Expand Down Expand Up @@ -593,6 +599,10 @@ public void onAudioMixFileSelectionClicked() {
dialog.setDialogSelectionListener(new DialogSelectionListener() {
@Override
public void onSelectedFilePaths(String[] files) {
if (files == null || files.length == 0) {
Toast.makeText(AVStreamingActivity.this, "Choose an audio please!", Toast.LENGTH_SHORT).show();
return;
}
String filePath = files[0];
try {
mAudioMixer.setFile(filePath, true);
Expand Down Expand Up @@ -743,7 +753,9 @@ public boolean onOrientationChanged(boolean isPortrait) {
return false;
}
Log.i(TAG, "isPortrait : " + isPortrait);
mOrientationChanged = true;
if (mIsStreaming) {
mOrientationChanged = true;
}
mProfile.setEncodingOrientation(isPortrait ? StreamingProfile.ENCODING_ORIENTATION.PORT : StreamingProfile.ENCODING_ORIENTATION.LAND);

// 更新 StreamingProfile 的时候,需要重新推流才可以生效!!!
Expand Down Expand Up @@ -1298,16 +1310,23 @@ public void run() {
}

private void stopStreamingInternal() {
if (mMediaStreamingManager == null) {
if (mMediaStreamingManager == null || !mIsStreaming) {
return;
}
final boolean res = mMediaStreamingManager.stopStreaming();
runOnUiThread(new Runnable() {
@Override
public void run() {
mControlFragment.setShutterButtonPressed(!res);
}
});
if (mSubThreadHandler != null) {
mSubThreadHandler.post(new Runnable() {
@Override
public void run() {
final boolean res = mMediaStreamingManager.stopStreaming();
runOnUiThread(new Runnable() {
@Override
public void run() {
mControlFragment.setShutterButtonPressed(!res);
}
});
}
});
}
}

private boolean isPictureStreaming() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class AudioStreamingActivity extends Activity {
private boolean mShutterButtonPressed = false;
private String mPublishUrl;
private boolean mIsQuicEnabled;
private boolean mIsSrtEnabled;
private boolean mIsReady;
private boolean mAudioStereoEnable = false;

Expand All @@ -65,6 +66,7 @@ protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
mPublishUrl = intent.getStringExtra(Config.PUBLISH_URL);
mIsQuicEnabled = intent.getBooleanExtra(Config.TRANSFER_MODE_QUIC, false);
mIsSrtEnabled = intent.getBooleanExtra(Config.TRANSFER_MODE_SRT, false);
mAudioStereoEnable = intent.getBooleanExtra(Config.AUDIO_CHANNEL_STEREO, false);

HandlerThread handlerThread = new HandlerThread(TAG);
Expand Down Expand Up @@ -145,6 +147,7 @@ private void initEncodingProfile() {
// 是否开启 QUIC 推流。
// QUIC 是基于 UDP 开发的可靠传输协议,在弱网下拥有更好的推流效果,相比于 TCP 拥有更低的延迟,可抵抗更高的丢包率。
mProfile.setQuicEnable(mIsQuicEnabled);
mProfile.setSrtEnabled(mIsSrtEnabled);

// 自定义配置音频的采样率、码率以及声道数的对象,如果使用预设配置,则无需实例化
StreamingProfile.AudioProfile aProfile = null;
Expand Down Expand Up @@ -396,15 +399,25 @@ public void run() {
* 停止推流
*/
private void stopStreamingInternal() {
if (mShutterButtonPressed) {
if (mShutterButtonPressed && mSubThreadHandler != null) {
// disable the shutter button before stopStreaming
setShutterButtonEnabled(false);
boolean res = mMediaStreamingManager.stopStreaming();
if (!res) {
mShutterButtonPressed = true;
setShutterButtonEnabled(true);
}
setShutterButtonPressed(mShutterButtonPressed);
mSubThreadHandler.post(new Runnable() {
@Override
public void run() {
final boolean res = mMediaStreamingManager.stopStreaming();
runOnUiThread(new Runnable() {
@Override
public void run() {
if (!res) {
mShutterButtonPressed = true;
setShutterButtonEnabled(true);
}
setShutterButtonPressed(mShutterButtonPressed);
}
});
}
});
}
}

Expand Down
Loading

0 comments on commit fa2f161

Please sign in to comment.