123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- package com.shuangyubang.mofun_flutter_plugin_video.mixplayer;
-
- import android.content.Context;
- import android.media.AudioFormat;
- import android.media.AudioManager;
- import android.media.AudioTrack;
- import android.os.Build;
- import android.util.Log;
-
- import static java.lang.Thread.sleep;
-
- /**
- * Created by rt-zl on 2019/2/15.
- */
-
- public class Render extends VideoRender {
-
-
- static {
- System.loadLibrary("mixplayer");
- }
-
- private long handler = 0;
-
- private native int setRenderHandler(long handler);
-
- int asample, ach, abit;
-
- public int mixUpdateAudio(byte[] data, int size, double pts) {
- playTime = pts;
- synchronized (audioBufLock) {
- if (audioBufLen - audioHas < size) {
- return -1;
- }
- int len = audioBufLen - audioWPos;
- len = len > size ? size : len;
- System.arraycopy(data, 0, audioBuf, audioWPos, len);
- audioWPos += len;
- audioHas += len;
- if (audioWPos == audioBufLen) {
- audioWPos = 0;
- }
- if (len < size) {
- int les = size - len;
- System.arraycopy(data, len, audioBuf, audioWPos, les);
- audioWPos += les;
- audioHas += les;
- }
- return 0;
- }
- }
-
-
- public int mixOpen(int vWidth, int vHeight, int asample, int ach, int abit) {
- if (vWidth > 0) {
- Log.d("MIXOPEN", "has video");
- nativeInit(getScreenWidth(), getScreenHeight());
- this.abit = abit;
- this.asample = asample;
- this.ach = ach;
- initAudioTrack();
- return 0;
- }
- return -1;
- }
-
-
- public void mixClose() {
- super.close();
- }
-
- public void renderClose() {
- play = false;
- if (audioTrack != null) {
- audioTrack.stop();
- totalAudioBuf = 0;
- }
- }
-
- public Render(Context context) {
- super(context);
- }
-
- public void init(long handler) {
- this.handler = handler;
- setMixHander(handler);
- this.setRenderHandler(handler);
- }
-
- public double getPlaytime() {
- return playTime;
- }
-
- AudioTrack audioTrack;
-
- final Object audioBufLock = new Object();
- byte[] audioBuf;
- long totalAudioBuf;
- int audioHas;
- int audioRPos, audioWPos;
- int audioBufLen = 4096 * 3;
- long silenceLen = 0;
- boolean play = false;
- double playTime = 0;
- byte[] silencBuf;
-
- private void initAudioTrack() {
- silencBuf = new byte[4096];
- synchronized (audioBufLock) {
- audioBuf = new byte[audioBufLen];
- }
- audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, asample,
- AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, audioBufLen, AudioTrack.MODE_STREAM);
- play = true;
- new Thread(() -> {
- int wsize = 1024;
- long posPre = 0;
- boolean needUpdate = false;
- int retryCount = 0;
- while (play) {
- synchronized (audioBufLock) {
- long pos = audioTrack.getPlaybackHeadPosition();
- // 16bit 2channels = 4 Byte
- pos *= 4;
- pos -= silenceLen;
- if (posPre != pos) {
- posPre = pos;
- retryCount = 0;
- } else {
- if (retryCount > 5)
- needUpdate = true;
- retryCount++;
- }
- if (audioHas >= wsize && totalAudioBuf - pos < audioBufLen || pos <= 0 || needUpdate) {
- needUpdate = false;
- int len = audioBufLen - audioRPos;
- len = len > wsize ? wsize : len;
- int ret = audioTrack.write(audioBuf, audioRPos, len);
- audioRPos += ret;
- audioHas -= ret;
- totalAudioBuf += ret;
- if (audioRPos == audioBufLen) {
- audioRPos = 0;
- }
- } else {
- // if (pos == totalAudioBuf && audioHas < wsize){
- // int c = audioTrack.write(silencBuf,0,2048);
- // silenceLen +=c;
- // }
- }
- if (ispause) {
- if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PAUSED) {
- audioTrack.pause();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- audioTrack.setVolume(0);
- } else {
- audioTrack.setStereoVolume(0, 0);
- }
- }
- } else {
- if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
- audioTrack.play();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- audioTrack.setVolume(volume);
- } else {
- audioTrack.setStereoVolume(volume, volume);
- }
- }
- }
- }
- try {
- sleep(3);
- } catch (Exception ignored) {
- }
- }
- Log.d("mixplayer", "audio close");
- }).start();
- audioTrack.play();
- }
-
- @Override
- protected void finalize() throws Throwable {
- super.finalize();
- play = false;
- renderClose();
- }
-
- }
|