You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
7.3 KiB
Java
276 lines
7.3 KiB
Java
package net.ossrs.yasea;
|
|
|
|
import android.content.Context;
|
|
import android.media.AudioManager;
|
|
import android.media.AudioRecord;
|
|
|
|
import com.github.faucamp.simplertmp.RtmpHandler;
|
|
import com.seu.magicfilter.utils.MagicFilterType;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
|
|
/**
|
|
* Created by Leo Ma on 2016/7/25.
|
|
*/
|
|
public class SrsPublisher {
|
|
|
|
private AudioRecord mic;
|
|
private boolean aloop = false;
|
|
private Thread aworker;
|
|
|
|
private SrsCameraView mCameraView;
|
|
|
|
private boolean sendAudioOnly = false;
|
|
private int videoFrameCount;
|
|
private long lastTimeMillis;
|
|
private double mSamplingFps;
|
|
|
|
private SrsFlvMuxer mFlvMuxer;
|
|
private SrsMp4Muxer mMp4Muxer;
|
|
private SrsEncoder mEncoder = new SrsEncoder();
|
|
|
|
public SrsPublisher(SrsCameraView view) {
|
|
mCameraView = view;
|
|
mCameraView.setPreviewCallback(new SrsCameraView.PreviewCallback() {
|
|
@Override
|
|
public void onGetRgbaFrame(byte[] data, int width, int height) {
|
|
calcSamplingFps();
|
|
if (!sendAudioOnly) {
|
|
mEncoder.onGetRgbaFrame(data, width, height);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private void calcSamplingFps() {
|
|
// Calculate sampling FPS
|
|
if (videoFrameCount == 0) {
|
|
lastTimeMillis = System.nanoTime() / 1000000;
|
|
videoFrameCount++;
|
|
} else {
|
|
if (++videoFrameCount >= 48) {
|
|
long diffTimeMillis = System.nanoTime() / 1000000 - lastTimeMillis;
|
|
mSamplingFps = (double) videoFrameCount * 1000 / diffTimeMillis;
|
|
videoFrameCount = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void startEncode() {
|
|
if (!mEncoder.start()) {
|
|
return;
|
|
}
|
|
|
|
mic = mEncoder.chooseAudioRecord();
|
|
if (mic == null) {
|
|
return;
|
|
}
|
|
|
|
if (!mCameraView.startCamera()) {
|
|
mEncoder.stop();
|
|
return;
|
|
}
|
|
|
|
aworker = new Thread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
|
|
startAudio();
|
|
}
|
|
});
|
|
aloop = true;
|
|
aworker.start();
|
|
}
|
|
|
|
public void stopEncode() {
|
|
stopAudio();
|
|
mCameraView.stopCamera();
|
|
mEncoder.stop();
|
|
}
|
|
|
|
public void startPublish(String rtmpUrl) {
|
|
if (mFlvMuxer != null) {
|
|
try {
|
|
mFlvMuxer.start(rtmpUrl);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
return;
|
|
}
|
|
mFlvMuxer.setVideoResolution(mEncoder.getOutputWidth(), mEncoder.getOutputHeight());
|
|
|
|
startEncode();
|
|
}
|
|
}
|
|
|
|
public void stopPublish() {
|
|
if (mFlvMuxer != null) {
|
|
stopEncode();
|
|
mFlvMuxer.stop();
|
|
}
|
|
}
|
|
|
|
public void startRecord(String recPath) {
|
|
if (mMp4Muxer != null) {
|
|
try {
|
|
mMp4Muxer.record(new File(recPath));
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void stopRecord() {
|
|
if (mMp4Muxer != null) {
|
|
mMp4Muxer.stop();
|
|
}
|
|
}
|
|
|
|
public void pauseRecord() {
|
|
if (mMp4Muxer != null) {
|
|
mMp4Muxer.pause();
|
|
}
|
|
}
|
|
|
|
public void resumeRecord() {
|
|
if (mMp4Muxer != null) {
|
|
mMp4Muxer.resume();
|
|
}
|
|
}
|
|
|
|
public void swithToSoftEncoder() {
|
|
mEncoder.swithToSoftEncoder();
|
|
}
|
|
|
|
public void swithToHardEncoder() {
|
|
mEncoder.swithToHardEncoder();
|
|
}
|
|
|
|
public boolean isSoftEncoder() {
|
|
return mEncoder.isSoftEncoder();
|
|
}
|
|
|
|
public int getPreviewWidth() {
|
|
return mEncoder.getPreviewWidth();
|
|
}
|
|
|
|
public int getPreviewHeight() {
|
|
return mEncoder.getPreviewHeight();
|
|
}
|
|
|
|
public double getmSamplingFps() {
|
|
return mSamplingFps;
|
|
}
|
|
|
|
public int getCamraId() {
|
|
return mCameraView.getCameraId();
|
|
}
|
|
|
|
public void setPreviewResolution(int width, int height) {
|
|
mCameraView.setPreviewResolution(width, height);
|
|
mEncoder.setPreviewResolution(width, height);
|
|
}
|
|
|
|
public void setOutputResolution(int width, int height) {
|
|
if (width <= height) {
|
|
mEncoder.setPortraitResolution(width, height);
|
|
} else {
|
|
mEncoder.setLandscapeResolution(width, height);
|
|
}
|
|
}
|
|
|
|
public void setScreenOrientation(int orientation) {
|
|
mEncoder.setScreenOrientation(orientation);
|
|
}
|
|
|
|
public void setPreviewRotation(int rotation) {
|
|
mCameraView.setPreviewRotation(rotation);
|
|
}
|
|
|
|
public void setVideoHDMode() {
|
|
mEncoder.setVideoHDMode();
|
|
}
|
|
|
|
public void setVideoSmoothMode() {
|
|
mEncoder.setVideoSmoothMode();
|
|
}
|
|
|
|
public void setSendAudioOnly(boolean flag) {
|
|
sendAudioOnly = flag;
|
|
}
|
|
|
|
public boolean switchCameraFilter(MagicFilterType type) {
|
|
return mCameraView.setFilter(type);
|
|
}
|
|
|
|
public void switchCameraFace(int id) {
|
|
mCameraView.setCameraId(id);
|
|
mCameraView.stopCamera();
|
|
if (id == 0) {
|
|
mEncoder.setCameraBackFace();
|
|
} else {
|
|
mEncoder.setCameraFrontFace();
|
|
}
|
|
mCameraView.startCamera();
|
|
}
|
|
|
|
private void startAudio() {
|
|
if (mic != null) {
|
|
mic.startRecording();
|
|
|
|
byte pcmBuffer[] = new byte[4096];
|
|
while (aloop && !Thread.interrupted()) {
|
|
int size = mic.read(pcmBuffer, 0, pcmBuffer.length);
|
|
if (size <= 0) {
|
|
break;
|
|
}
|
|
mEncoder.onGetPcmFrame(pcmBuffer, size);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void stopAudio() {
|
|
aloop = false;
|
|
if (aworker != null) {
|
|
aworker.interrupt();
|
|
try {
|
|
aworker.join();
|
|
} catch (InterruptedException e) {
|
|
e.printStackTrace();
|
|
aworker.interrupt();
|
|
}
|
|
aworker = null;
|
|
}
|
|
|
|
if (mic != null) {
|
|
mic.setRecordPositionUpdateListener(null);
|
|
mic.stop();
|
|
mic.release();
|
|
mic = null;
|
|
}
|
|
}
|
|
|
|
public void switchMute() {
|
|
AudioManager audioManager = (AudioManager) mCameraView.getContext().getSystemService(Context.AUDIO_SERVICE);
|
|
int oldMode = audioManager.getMode();
|
|
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
|
boolean isMute = !audioManager.isMicrophoneMute();
|
|
audioManager.setMicrophoneMute(isMute);
|
|
audioManager.setMode(oldMode);
|
|
}
|
|
|
|
public void setRtmpHandler(RtmpHandler handler) {
|
|
mFlvMuxer = new SrsFlvMuxer(handler);
|
|
mEncoder.setFlvMuxer(mFlvMuxer);
|
|
}
|
|
|
|
public void setRecordHandler(SrsRecordHandler handler) {
|
|
mMp4Muxer = new SrsMp4Muxer(handler);
|
|
mEncoder.setMp4Muxer(mMp4Muxer);
|
|
}
|
|
|
|
public void setNetworkHandler(SrsNetworkHandler handler) {
|
|
mEncoder.setNetworkEventHandler(handler);
|
|
}
|
|
}
|