You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.4 KiB
130 lines
4.4 KiB
package com.frank.live;
|
|
|
|
import android.Manifest;
|
|
import android.annotation.SuppressLint;
|
|
import android.annotation.TargetApi;
|
|
import android.media.AudioFormat;
|
|
import android.os.Build;
|
|
import android.os.Handler;
|
|
import android.os.Message;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.appcompat.app.AppCompatActivity;
|
|
|
|
import android.os.Bundle;
|
|
import android.text.TextUtils;
|
|
import android.util.Log;
|
|
import android.view.TextureView;
|
|
import android.view.View;
|
|
import android.widget.CompoundButton;
|
|
import android.widget.Toast;
|
|
import android.widget.ToggleButton;
|
|
|
|
import com.frank.live.Push.LivePusher;
|
|
import com.frank.live.camera2.Camera2Helper;
|
|
import com.frank.live.listener.LiveStateChangeListener;
|
|
import com.frank.live.param.AudioParam;
|
|
import com.frank.live.param.VideoParam;
|
|
|
|
/**
|
|
* h264与rtmp实时推流直播
|
|
* Created by frank on 2018/1/28.
|
|
*/
|
|
|
|
public class RtmpLiveActivity extends AppCompatActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener, LiveStateChangeListener {
|
|
|
|
private final static String TAG = RtmpLiveActivity.class.getSimpleName();
|
|
private final static int CODE_CAMERA_RECORD = 0x0001;
|
|
private final static String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
|
|
private final static String LIVE_URL = "rtmp://192.168.1.3/live/stream";
|
|
private final static int MSG_ERROR = 100;
|
|
private TextureView textureView;
|
|
private LivePusher livePusher;
|
|
@SuppressLint("HandlerLeak")
|
|
private Handler mHandler = new Handler() {
|
|
@Override
|
|
public void handleMessage(Message msg) {
|
|
super.handleMessage(msg);
|
|
if (msg.what == MSG_ERROR) {
|
|
String errMsg = (String) msg.obj;
|
|
if (!TextUtils.isEmpty(errMsg)) {
|
|
Toast.makeText(RtmpLiveActivity.this, errMsg, Toast.LENGTH_SHORT).show();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_rtmp_live);
|
|
|
|
initView();
|
|
requirePermission();
|
|
initPusher();
|
|
}
|
|
|
|
private void initView() {
|
|
findViewById(R.id.btn_swap).setOnClickListener(this);
|
|
((ToggleButton) findViewById(R.id.btn_live)).setOnCheckedChangeListener(this);
|
|
textureView = findViewById(R.id.surface_camera);
|
|
}
|
|
|
|
private void initPusher() {
|
|
int width = 640;//分辨率设置很重要
|
|
int height = 480;
|
|
int videoBitRate = 400;//kb/s jason-->480kb
|
|
int videoFrameRate = 25;//fps
|
|
VideoParam videoParam = new VideoParam(width, height,
|
|
Integer.valueOf(Camera2Helper.CAMERA_ID_BACK), videoBitRate, videoFrameRate);
|
|
int sampleRate = 44100;//采样率:Hz
|
|
int channelConfig = AudioFormat.CHANNEL_IN_STEREO;//立体声道
|
|
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;//pcm16位
|
|
int numChannels = 2;//声道数
|
|
AudioParam audioParam = new AudioParam(sampleRate, channelConfig, audioFormat, numChannels);
|
|
livePusher = new LivePusher(textureView, videoParam, audioParam, this);
|
|
}
|
|
|
|
@Override
|
|
public void onClick(View v) {
|
|
if (v.getId() == R.id.btn_swap) {
|
|
livePusher.switchCamera();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
if (isChecked) {
|
|
livePusher.startPush(LIVE_URL, this);
|
|
} else {
|
|
livePusher.stopPush();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onError(String msg) {
|
|
Log.e(TAG, "errMsg=" + msg);
|
|
mHandler.obtainMessage(MSG_ERROR, msg).sendToTarget();
|
|
}
|
|
|
|
@TargetApi(Build.VERSION_CODES.M)
|
|
private void requirePermission() {
|
|
requestPermissions(permissions, CODE_CAMERA_RECORD);
|
|
}
|
|
|
|
@Override
|
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
if (permissions.length > 0 && grantResults.length == permissions.length) {
|
|
for (int i = 0; i < permissions.length; i++) {
|
|
Log.i(TAG, permissions[i] + ":grantResult=" + grantResults[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onDestroy() {
|
|
super.onDestroy();
|
|
livePusher.release();
|
|
}
|
|
}
|
|
|