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.
MpLive/library/src/main/java/net/ossrs/yasea/SrsPublisher.java

289 lines
7.7 KiB
Java

package net.ossrs.yasea;
import android.content.Context;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.audiofx.AcousticEchoCanceler;
import android.media.audiofx.AutomaticGainControl;
import com.github.faucamp.simplertmp.RtmpHandler;
import com.seu.magicfilter.utils.MagicFilterType;
import java.io.File;
/**
* Created by Leo Ma on 2016/7/25.
*/
public class SrsPublisher {
private static AudioRecord mic;
private static AcousticEchoCanceler aec;
private static AutomaticGainControl agc;
private byte[] mPcmBuffer = new byte[4096];
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;
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 >= SrsEncoder.VGOP) {
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 (AcousticEchoCanceler.isAvailable()) {
aec = AcousticEchoCanceler.create(mic.getAudioSessionId());
if (aec != null) {
aec.setEnabled(true);
}
}
if (AutomaticGainControl.isAvailable()) {
agc = AutomaticGainControl.create(mic.getAudioSessionId());
if (agc != null) {
agc.setEnabled(true);
}
}
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) {
mFlvMuxer.start(rtmpUrl);
mFlvMuxer.setVideoResolution(mEncoder.getOutputWidth(), mEncoder.getOutputHeight());
startEncode();
}
}
public void stopPublish() {
if (mFlvMuxer != null) {
stopEncode();
mFlvMuxer.stop();
}
}
public boolean startRecord(String recPath) {
return mMp4Muxer != null && mMp4Muxer.record(new File(recPath));
}
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) {
int resolution[] = mCameraView.setPreviewResolution(width, height);
mEncoder.setPreviewResolution(resolution[0], resolution[1]);
}
public void setOutputResolution(int width, int height) {
if (width <= height) {
mEncoder.setPortraitResolution(width, height);
} else {
mEncoder.setLandscapeResolution(width, height);
}
}
public void setScreenOrientation(int orientation) {
mCameraView.setPreviewOrientation(orientation);
mEncoder.setScreenOrientation(orientation);
}
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();
while (aloop && !Thread.interrupted()) {
int size = mic.read(mPcmBuffer, 0, mPcmBuffer.length);
if (size <= 0) {
break;
}
mEncoder.onGetPcmFrame(mPcmBuffer, size);
}
}
}
private void stopAudio() {
aloop = false;
if (aworker != null) {
aworker.interrupt();
try {
aworker.join();
} catch (InterruptedException e) {
aworker.interrupt();
}
aworker = null;
}
if (mic != null) {
mic.setRecordPositionUpdateListener(null);
mic.stop();
mic.release();
mic = null;
}
if (aec != null) {
aec.setEnabled(false);
aec.release();
aec = null;
}
if (agc != null) {
agc.setEnabled(false);
agc.release();
agc = null;
}
}
public void setRtmpHandler(RtmpHandler handler) {
mFlvMuxer = new SrsFlvMuxer(handler);
if (mEncoder != null) {
mEncoder.setFlvMuxer(mFlvMuxer);
}
}
public void setRecordHandler(SrsRecordHandler handler) {
mMp4Muxer = new SrsMp4Muxer(handler);
if (mEncoder != null) {
mEncoder.setMp4Muxer(mMp4Muxer);
}
}
public void setEncodeHandler(SrsEncodeHandler handler) {
mEncoder = new SrsEncoder(handler);
if (mFlvMuxer != null) {
mEncoder.setFlvMuxer(mFlvMuxer);
}
if (mMp4Muxer != null) {
mEncoder.setMp4Muxer(mMp4Muxer);
}
}
}