24
24
import com .google .zxing .integration .android .IntentResult ;
25
25
import com .qiniu .pili .droid .streaming .PLAuthenticationResultCallback ;
26
26
import com .qiniu .pili .droid .streaming .StreamingEnv ;
27
+ import com .qiniu .pili .droid .streaming .common .FileLogHelper ;
27
28
import com .qiniu .pili .droid .streaming .demo .activity .AVStreamingActivity ;
28
29
import com .qiniu .pili .droid .streaming .demo .activity .AudioStreamingActivity ;
29
30
import com .qiniu .pili .droid .streaming .demo .activity .ImportStreamingActivity ;
35
36
import com .qiniu .pili .droid .streaming .demo .utils .PermissionChecker ;
36
37
import com .qiniu .pili .droid .streaming .demo .utils .Util ;
37
38
39
+ import java .net .URI ;
40
+ import java .net .URISyntaxException ;
38
41
import java .util .Arrays ;
42
+ import java .util .List ;
39
43
import java .util .UUID ;
40
44
41
45
public class MainActivity extends FragmentActivity {
@@ -56,7 +60,9 @@ public class MainActivity extends FragmentActivity {
56
60
private TextView mInputTextTV ;
57
61
private Spinner mStreamTypeSpinner ;
58
62
private CheckBox mDebugModeCheckBox ;
63
+ private RadioButton mRtmpPushButton ;
59
64
private RadioButton mQuicPushButton ;
65
+ private RadioButton mSrtPushButton ;
60
66
61
67
private EncodingConfigFragment mEncodingConfigFragment ;
62
68
private CameraConfigFragment mCameraConfigFragment ;
@@ -67,31 +73,58 @@ public class MainActivity extends FragmentActivity {
67
73
protected void onCreate (Bundle savedInstanceState ) {
68
74
super .onCreate (savedInstanceState );
69
75
setContentView (R .layout .activity_main );
70
- // 开启日志的本地保存,保存在应用私有目录(getExternalFilesDir) 或者 getFilesDir 文件目录下的 Pili 文件夹中
71
- StreamingEnv .setLogLevel (Log .INFO );
72
- StreamingEnv .startLogFile ();
73
76
74
77
TextView versionInfo = (TextView ) findViewById (R .id .version_info );
75
78
mInputTextTV = (TextView ) findViewById (R .id .input_url );
76
79
mStreamTypeSpinner = (Spinner ) findViewById (R .id .stream_types );
77
80
mDebugModeCheckBox = (CheckBox ) findViewById (R .id .debug_mode );
81
+ mRtmpPushButton = (RadioButton ) findViewById (R .id .transfer_rtmp );
78
82
mQuicPushButton = (RadioButton ) findViewById (R .id .transfer_quic );
83
+ mSrtPushButton = (RadioButton ) findViewById (R .id .transfer_srt );
79
84
80
- mInputTextTV .setText (Cache .retrieveURL (this ));
85
+ String publishUrl = Cache .retrieveURL (this );
86
+ if (publishUrl .startsWith ("srt" )) {
87
+ mSrtPushButton .setChecked (true );
88
+ } else {
89
+ mRtmpPushButton .setChecked (true );
90
+ }
91
+ mInputTextTV .setText (publishUrl );
81
92
82
93
FragmentManager fragmentManager = getSupportFragmentManager ();
83
94
mEncodingConfigFragment = (EncodingConfigFragment ) fragmentManager .findFragmentById (R .id .encoding_config_fragment );
84
95
mCameraConfigFragment = (CameraConfigFragment ) fragmentManager .findFragmentById (R .id .camera_config_fragment );
85
96
86
97
versionInfo .setText ("versionName: " + BuildConfig .VERSION_NAME + " versionCode: " + BuildConfig .VERSION_CODE );
98
+ versionInfo .setOnLongClickListener (new View .OnLongClickListener () {
99
+ @ Override
100
+ public boolean onLongClick (View v ) {
101
+ StreamingEnv .reportLogFiles (new FileLogHelper .LogReportCallback () {
102
+ @ Override
103
+ public void onReportSuccess (List <String > logNames ) {
104
+ if (logNames .size () == 0 ) {
105
+ return ;
106
+ }
107
+ for (String logName : logNames ) {
108
+ Log .i (TAG , logName );
109
+ }
110
+ Log .i (TAG , "日志已上传" );
111
+ Toast .makeText (MainActivity .this , "日志已上传!" , Toast .LENGTH_SHORT ).show ();
112
+ }
113
+
114
+ @ Override
115
+ public void onReportError (String name , String errorMsg ) {
116
+ Toast .makeText (MainActivity .this , "日志 " + name + " 上传失败: " + errorMsg , Toast .LENGTH_SHORT ).show ();
117
+ }
118
+ });
119
+ return true ;
120
+ }
121
+ });
87
122
initStreamTypeSpinner ();
88
123
}
89
124
90
125
@ Override
91
126
protected void onDestroy () {
92
127
super .onDestroy ();
93
- StreamingEnv .stopLogFile ();
94
- Log .i (TAG , "Log file path : " + StreamingEnv .getLogFilePath ());
95
128
}
96
129
97
130
@ Override
@@ -129,17 +162,24 @@ public void launchStreaming(View v) {
129
162
Util .showToast (this , "推流地址不能为空!!!" );
130
163
return ;
131
164
}
165
+ if ((mSrtPushButton .isChecked () && !streamText .startsWith ("srt" ))
166
+ || (!mSrtPushButton .isChecked () && !streamText .startsWith ("rtmp" ))) {
167
+ Util .showToast (this , "请检查推流地址和协议是否匹配!!!" );
168
+ return ;
169
+ }
132
170
133
171
if (mDebugModeCheckBox .isChecked ()) {
134
172
StreamingEnv .setLogLevel (Log .VERBOSE );
135
173
}
136
174
137
175
boolean quicEnable = mQuicPushButton .isChecked ();
176
+ boolean srtEnable = mSrtPushButton .isChecked ();
138
177
139
178
int pos = mStreamTypeSpinner .getSelectedItemPosition ();
140
179
Intent intent = new Intent (this , ACTIVITY_CLASSES [pos ]);
141
180
intent .putExtra (Config .PUBLISH_URL , streamText );
142
181
intent .putExtra (Config .TRANSFER_MODE_QUIC , quicEnable );
182
+ intent .putExtra (Config .TRANSFER_MODE_SRT , srtEnable );
143
183
intent .putExtras (mEncodingConfigFragment .getIntent ());
144
184
boolean isAudioStereo = ((CheckBox ) findViewById (R .id .audio_channel_stereo )).isChecked ();
145
185
intent .putExtra (Config .AUDIO_CHANNEL_STEREO , isAudioStereo );
@@ -182,6 +222,9 @@ public void onClickGenPublishURL(View v) {
182
222
@ Override
183
223
public void run () {
184
224
String publishUrl = genPublishURL ();
225
+ if (mSrtPushButton .isChecked () && publishUrl .startsWith ("rtmp://" )) {
226
+ publishUrl = getSrtPublishUrl (publishUrl );
227
+ }
185
228
if (publishUrl != null ) {
186
229
Cache .saveURL (MainActivity .this , publishUrl );
187
230
updateInputTextView (publishUrl );
@@ -255,6 +298,35 @@ private String genPublishURL() {
255
298
return publishUrl ;
256
299
}
257
300
301
+ /**
302
+ * 自定义组装 SRT 推流地址
303
+ *
304
+ * 建议由您业务服务端生成符合规范的 SRT 推流地址
305
+ * 地址规范可参考:https://github.com/Haivision/srt/blob/master/docs/features/access-control.md#general-syntax
306
+ *
307
+ * @param rtmpUrl rtmp 地址
308
+ * @return 组装的 SRT 地址
309
+ */
310
+ private String getSrtPublishUrl (String rtmpUrl ) {
311
+ URI u ;
312
+ try {
313
+ u = new URI (rtmpUrl );
314
+ String path = u .getPath ().substring (1 );
315
+ String query = u .getQuery ();
316
+ StringBuilder publishUrl = new StringBuilder (String .format ("srt://%s?streamid=#!::h=%s,m=publish" , u .getHost (), path ));
317
+ if (query != null ) {
318
+ String [] queries = query .split ("&" );
319
+ for (String q : queries ) {
320
+ publishUrl .append ("," ).append (q );
321
+ }
322
+ }
323
+ return publishUrl .toString ();
324
+ } catch (URISyntaxException e ) {
325
+ e .printStackTrace ();
326
+ }
327
+ return "" ;
328
+ }
329
+
258
330
private void updateInputTextView (final String url ) {
259
331
runOnUiThread (new Runnable () {
260
332
@ Override
0 commit comments