StreamActivity.java
10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
package com.cnlive.demo.stream;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import com.cnlive.libs.stream.CNLiveStramer;
import com.cnlive.libs.stream.CNStreamer;
import com.cnlive.libs.stream.StreamConfig;
import com.cnlive.libs.stream.StreamerCallBack;
import com.cnlive.libs.stream.model.CNStreamerBuilder;
import java.util.Random;
/**
* Created by Administrator on 2016/8/29.
*/
public class StreamActivity extends Activity {
private Button button;
private String activityid = "" + System.currentTimeMillis();
private String channelid = "" + System.currentTimeMillis();
private int isHorizon = 1;
private boolean initDone = false;
protected CNLiveStramer streamer;
private GLSurfaceView camera_preview;
private long lastClickTime = 0;
private StreamUtilCallback callback = new StreamUtilCallback();
CNStreamerBuilder.Builder cnBuilder = new CNStreamerBuilder.Builder();
@Override
protected void onCreate(Bundle savedInstanceState) {
new Random().nextInt();
super.onCreate(savedInstanceState);
setContentView(R.layout.stream_activity);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Intent intent = getIntent();
activityid = intent.getStringExtra("activityId");
channelid = intent.getStringExtra("channelId");
button = (Button) findViewById(R.id.button);
button.setOnClickListener(listener);
camera_preview = (GLSurfaceView) findViewById(R.id.camera_preview);
//初始化 CNStreamer 对象
streamer = new CNLiveStramer(callback, camera_preview);
//设置 配置信息
streamer.setCnBuilder(newBuilder(false, 15, 800, CNStreamer.RESOLUTION_480P, false));
//创建 直播 (CNLiveStramer对象 createLive()创建直播成功后 无法再次创建)
streamer.createLive();
}
//设置 直播节目 属性
private void setStreamData() {
cnBuilder.setActivityID(activityid);
cnBuilder.setChannelID(channelid);
cnBuilder.setIsHorizontalScreen(isHorizon);
//下面注释掉的参数为非必传参数,可以传也可以不传
// cnBuilder.setActivityName("");//活动名称
// cnBuilder.setActivityStatus(0);//活动状态
// cnBuilder.setStartTime("");//开始时间
// cnBuilder.setEndTime("");//结束时间
// cnBuilder.setCoverImgUrl("");//活动封面
// cnBuilder.setActivityCategory("");//活动分类
// cnBuilder.setExtensions("");//
// cnBuilder.setUuid("");//用户设备号
// cnBuilder.setCallbackAcitvityStatushttpPostUrl("");//回调通知活动状态
}
protected boolean checkLastClick() {
long curTime = System.currentTimeMillis();
if (curTime - lastClickTime < 1000) {
return false;
}
lastClickTime = curTime;
return true;
}
private View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!checkLastClick()) return;
switch (view.getId()) {
case R.id.button:
if (initDone)
if (!streamer.inLive()) {
streamer.startRecord();
button.setText("停止直播");
} else {
streamer.stopRecord();
button.setText("开始直播");
}
break;
}
}
};
private CNStreamerBuilder.Builder newBuilder(boolean landscape,
int frameRate,
int videoBitrate,
int videoResolution,
boolean hardware) {
//设置直播节目属性
setStreamData();
//设置 视频 属性
cnBuilder.setVideoResolution(CNStreamer.RESOLUTION_480P);
//帧率
cnBuilder.setFrameRate(frameRate);
//视频码率
cnBuilder.setMaxAverageVideoBitrate(videoBitrate);
cnBuilder.setMinAverageVideoBitrate(videoBitrate * 2 / 8);
cnBuilder.setInitAverageVideoBitrate(videoBitrate * 5 / 8);
//音频码率
cnBuilder.setAudioBitrate(48);
//分辨率
switch (videoResolution) {
case CNStreamer.RESOLUTION_360P:
case CNStreamer.RESOLUTION_480P:
case CNStreamer.RESOLUTION_540P:
case CNStreamer.RESOLUTION_720P:
cnBuilder.setVideoResolution(videoResolution);
break;
default:
cnBuilder.setVideoResolution(CNStreamer.RESOLUTION_480P);
break;
}
//设置启动硬件解码
cnBuilder.setEncodeMethodHardware(false);
//音频通道
cnBuilder.setSampleAudioRateInHz(44100);
cnBuilder.setEnableStreamStatModule(true);
//屏幕方向
cnBuilder.setDefaultLandscape(landscape);
//前置摄像头镜像
cnBuilder.setFrontCameraMirror(true);
//设置视频编码时的帧间隔 秒 默认3秒
cnBuilder.setIFrameIntervalSec(2);
return cnBuilder;
}
@Override
protected void onPause() {
super.onPause();
streamer.pause();
}
@Override
protected void onResume() {
super.onResume();
streamer.resume();
}
@Override
protected void onDestroy() {
super.onDestroy();
streamer.destroy();
}
//处理 SDK 状态
private class StreamUtilCallback implements StreamerCallBack {
@Override
public void onStreamerState(int what, String extra) {
if (what < 0) {
button.setText("开始直播");
}
switch (what) {
case StreamConfig.cnstream_init_done:
//初始化完成 后开始直播推流等操作
initDone = true;
break;
case StreamConfig.cnstream_init_error_instop:
//初始化失败 正在停止播放
break;
case StreamConfig.cnstream_error_create_stream_server:
//创建直播活动请求服务器失败
break;
case StreamConfig.cnstream_error_create_stream_network:
//创建直播活动时网络连接失败
break;
case StreamConfig.cnstream_error_create_stream_other:
//创建直播活动时失败
break;
case StreamConfig.cnstream_open_stream_succ:
break;
case StreamConfig.cnstream_auth_failed:
// "认证失败";
break;
case StreamConfig.cnstream_encoded_frames_threshold:
// "认证失败且超过编码上限";
break;
case StreamConfig.cnstream_encoded_frames_failed:
// "编码失败";
break;
case StreamConfig.cnstream_codec_open_failed:
// "推流失败";
break;
case StreamConfig.cnstream_codec_guess_format_failed:
// "推流失败";
break;
case StreamConfig.cnstream_connect_failed:
// "推流建立连接失败";
break;
case StreamConfig.cnstream_connect_break:
// "推流过程中断网络异常";
break;
case StreamConfig.cnstream_audio_init_failed:
// "合成音频失败";
break;
case StreamConfig.cnstream_open_camera_fall:
// "打开摄像头失败";
break;
case StreamConfig.cnstream_camera_disabled:
// "打开摄像头失败";
break;
case StreamConfig.cnstreamo_frame_data_send_slow:
//网络状态不佳
break;
case StreamConfig.cnstream_socket_disconnect:
//推流Socket异常断开
break;
case StreamConfig.cnstream_error_start_stream_server:
//开始直播时请求服务器失败
break;
case StreamConfig.cnstream_error_start_stream_network:
//开始直播时网络连接失败
break;
case StreamConfig.cnstream_error_start_stream_other:
//开始直播活动失败
break;
case StreamConfig.cnstream_dns_parse_failed:
//url域名解析失败
break;
case StreamConfig.cnstream_rtmp_publish_failed:
//网络建立成功后,推流失败
break;
case StreamConfig.cnstream_audio_covert_failed:
//转码失败
break;
case StreamConfig.cnstream_audio_start_failed:
//录音开始失败
break;
case StreamConfig.cnstream_est_bw_raise:
case StreamConfig.cnstream_est_bw_drop:
break;
}
if (what < 0) {
Log.e("DemoView", "errorCode : " + what + " errorMessage : " + extra);
Toast.makeText(StreamActivity.this, what + " " + extra, Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onBackPressed() {
if (streamer.inLive()) {
new AlertDialog.Builder(StreamActivity.this).setCancelable(true)
.setTitle("结束直播?")
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
}
})
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
streamer.stopRecord();
StreamActivity.this.finish();
}
}).show();
} else {
super.onBackPressed();
}
}
}