package net.ossrs.yasea; 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 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 startCamera() { mCameraView.startCamera(); } public void stopCamera() { mCameraView.stopCamera(); } public void startAudio() { 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); } } aworker = new Thread(new Runnable() { @Override public void run() { android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO); mic.startRecording(); while (!Thread.interrupted()) { int size = mic.read(mPcmBuffer, 0, mPcmBuffer.length); if (size <= 0) { break; } mEncoder.onGetPcmFrame(mPcmBuffer, size); } } }); aworker.start(); } public void stopAudio() { 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 startEncode() { if (!mEncoder.start()) { return; } startAudio(); } public void stopEncode() { stopAudio(); 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 switchToSoftEncoder() { mEncoder.switchToSoftEncoder(); } public void switchToHardEncoder() { mEncoder.switchToHardEncoder(); } 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) { if (mEncoder.isEnabled()) { mCameraView.stopCamera(); mCameraView.setCameraId(id); if (id == 0) { mEncoder.setCameraBackFace(); } else { mEncoder.setCameraFrontFace(); } mCameraView.startCamera(); } } 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); } } }