Browse Source

替换云教练评测播放器,修改优化作品合成部分问题

Pq 7 months ago
parent
commit
079afba6fe
24 changed files with 778 additions and 275 deletions
  1. 14 0
      BaseLibrary/src/main/java/com/cooleshow/base/utils/MyFileUtils.java
  2. 3 1
      accompany/build.gradle
  3. BIN
      accompany/libs/arm64-v8a/libijkffmpeg.so
  4. BIN
      accompany/libs/arm64-v8a/libijkplayer.so
  5. BIN
      accompany/libs/arm64-v8a/libijksdl.so
  6. BIN
      accompany/libs/armeabi-v7a/libijkffmpeg.so
  7. BIN
      accompany/libs/armeabi-v7a/libijkplayer.so
  8. BIN
      accompany/libs/armeabi-v7a/libijksdl.so
  9. 11 0
      accompany/src/main/java/com/daya/orchestra/accompany/callback/ResultCallbackV2.java
  10. 13 14
      accompany/src/main/java/com/daya/orchestra/accompany/helper/AccompanyPlayHelper.java
  11. 30 0
      accompany/src/main/java/com/daya/orchestra/accompany/player/BasePlayer.java
  12. 216 0
      accompany/src/main/java/com/daya/orchestra/accompany/player/CustomExoPlayer.java
  13. 226 0
      accompany/src/main/java/com/daya/orchestra/accompany/player/CustomIJKPlayer.java
  14. 8 0
      accompany/src/main/java/com/daya/orchestra/accompany/player/OnCompletionListener.java
  15. 0 226
      accompany/src/main/java/com/daya/orchestra/accompany/presenter/CustomIJKPlayer.java
  16. 163 0
      accompany/src/main/java/com/daya/orchestra/accompany/utils/MusicFileDownloadHelper.java
  17. 44 12
      accompany/src/main/java/com/daya/orchestra/accompany/web/AccompanyActivity.java
  18. 5 4
      accompany/src/main/java/com/daya/orchestra/accompany/web/AccompanyFragment.java
  19. 13 9
      ffmpegCmd/src/main/java/com/cooleshow/ffmpegcmd/util/FFmpegUtil.java
  20. 3 3
      musicMerge/src/main/java/com/cooleshow/musicmerge/helper/MixHelper.java
  21. 10 4
      musicMerge/src/main/java/com/cooleshow/musicmerge/player/CustomPlayer.java
  22. 5 0
      musicMerge/src/main/java/com/cooleshow/musicmerge/ui/MusicHandleActivity.java
  23. 8 2
      musicMerge/src/main/java/com/cooleshow/musicmerge/ui/MusicHandleActivity_.java
  24. 6 0
      musicMerge/src/main/java/com/cooleshow/musicmerge/ui/MusicHandleSettingFragment.java

+ 14 - 0
BaseLibrary/src/main/java/com/cooleshow/base/utils/MyFileUtils.java

@@ -80,6 +80,20 @@ public class MyFileUtils {
         }
     }
 
+    public static String getCacheDir2(Context context, String directory) {
+        String fileDir;
+        try {
+            File file = new File(context.getCacheDir() + File.separator + directory);
+            if (!file.exists()) {
+                file.mkdirs();
+            }
+            fileDir = file.getAbsolutePath();
+            return fileDir;
+        } catch (Exception e) {
+            return "";
+        }
+    }
+
     public static String getFilesDir(Context context) {
         try {
             File file = context.getExternalFilesDir(filesDirectory);

+ 3 - 1
accompany/build.gradle

@@ -81,5 +81,7 @@ dependencies {
     kapt "com.alibaba:arouter-compiler:$rootProject.ext.android.arouter_api_version"
 
     //ijkPlayer
-    api 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
+//    api 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
+
+    api 'com.google.android.exoplayer:exoplayer:2.15.0'
 }

BIN
accompany/libs/arm64-v8a/libijkffmpeg.so


BIN
accompany/libs/arm64-v8a/libijkplayer.so


BIN
accompany/libs/arm64-v8a/libijksdl.so


BIN
accompany/libs/armeabi-v7a/libijkffmpeg.so


BIN
accompany/libs/armeabi-v7a/libijkplayer.so


BIN
accompany/libs/armeabi-v7a/libijksdl.so


+ 11 - 0
accompany/src/main/java/com/daya/orchestra/accompany/callback/ResultCallbackV2.java

@@ -0,0 +1,11 @@
+package com.daya.orchestra.accompany.callback;
+
+/**
+ * Author by pq, Date on 2022/12/19.
+ */
+public interface ResultCallbackV2<Result> {
+    void onSuccess(Result result);
+    void onProgress(int progressPercent);
+
+    void onFail(int errorCode, String errorStr);
+}

+ 13 - 14
accompany/src/main/java/com/daya/orchestra/accompany/helper/AccompanyPlayHelper.java

@@ -1,11 +1,9 @@
 package com.daya.orchestra.accompany.helper;
 
 import android.content.Context;
-import android.media.MediaPlayer;
 import android.os.Handler;
 import android.os.Looper;
 import android.text.TextUtils;
-import android.util.Log;
 import android.webkit.ValueCallback;
 import android.webkit.WebView;
 
@@ -18,11 +16,12 @@ import com.cooleshow.base.utils.FileUtils;
 import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.utils.MyFileUtils;
 import com.cooleshow.base.utils.ToastUtil;
+import com.cooleshow.base.utils.Utils;
 import com.cooleshow.base.websocket.JWebSocketClient;
 import com.cooleshow.usercenter.helper.UserHelper;
 import com.daya.orchestra.accompany.common.Constants;
-import com.daya.orchestra.accompany.player.CustomPlayer;
-import com.daya.orchestra.accompany.presenter.CustomIJKPlayer;
+import com.daya.orchestra.accompany.player.CustomExoPlayer;
+import com.daya.orchestra.accompany.player.OnCompletionListener;
 
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -37,12 +36,11 @@ import io.reactivex.rxjava3.core.ObservableOnSubscribe;
 import io.reactivex.rxjava3.core.Observer;
 import io.reactivex.rxjava3.disposables.Disposable;
 import io.reactivex.rxjava3.schedulers.Schedulers;
-import tv.danmaku.ijk.media.player.IMediaPlayer;
 
 /**
  * Author by pq, Date on 2023/8/4.
  */
-public class AccompanyPlayHelper implements IMediaPlayer.OnCompletionListener {
+public class AccompanyPlayHelper implements OnCompletionListener {
     public static final String TAG = "AccPlayHelper";
 
     public static long realPlayStartTime = -1;
@@ -55,7 +53,7 @@ public class AccompanyPlayHelper implements IMediaPlayer.OnCompletionListener {
     public static final String BLANK_DEVICE_DELAY_CACHE_KEY = "delay_cache";
     public static final String DELAY_FOR_CURRENT_CACHE_KEY = "delayForCurrent";
     private Recorder wavRecorder;
-    private CustomIJKPlayer player;
+    private CustomExoPlayer player;
     private long startPlayTime = 0;
     private boolean isTag = true;
 
@@ -95,16 +93,17 @@ public class AccompanyPlayHelper implements IMediaPlayer.OnCompletionListener {
     private Runnable mRunnable2 = new Runnable() {
         @Override
         public void run() {
-            CustomIJKPlayer player = getPlayer();
+            CustomExoPlayer player = getPlayer();
             long cu = player.getCu();
             long duration = player.getT();
             long exceptTargetPos = player.getExceptTargetPos(cu);
             if (exceptTargetPos > 1000) {
                 if (isTag) {
-                    LOG.i(TAG, "第二段cu:" + exceptTargetPos);
-                    LOG.i(TAG, "第二段duration:" + duration);
                     long cTime = System.currentTimeMillis();
-                    long endTime = cTime - exceptTargetPos;
+                    LOG.i(TAG, "cTime:" + cTime);
+                    LOG.i(TAG, "playSpeed:" +  player.getSpeed());
+                    long preogressBySpeed= (long) (exceptTargetPos / player.getSpeed());
+                    long endTime = cTime - preogressBySpeed;
                     realPlayStartTime = endTime;
                     long delayTime = endTime - startPlayTime;
                     LOG.i(TAG, "第二段 delayTime:" + delayTime);
@@ -480,9 +479,9 @@ public class AccompanyPlayHelper implements IMediaPlayer.OnCompletionListener {
         wavRecorder = null;
     }
 
-    private CustomIJKPlayer getPlayer() {
+    private CustomExoPlayer getPlayer() {
         if (player == null) {
-            player = new CustomIJKPlayer();
+            player = new CustomExoPlayer(Utils.getApp());
             player.setOnCompletionListener(this);
         }
         return player;
@@ -546,7 +545,7 @@ public class AccompanyPlayHelper implements IMediaPlayer.OnCompletionListener {
 
 
     @Override
-    public void onCompletion(IMediaPlayer iMediaPlayer) {
+    public void onCompletion() {
         LOG.i(TAG, "play onCompletion");
         if (loopHandler != null) {
             loopHandler.removeCallbacks(mRunnable2);

+ 30 - 0
accompany/src/main/java/com/daya/orchestra/accompany/player/BasePlayer.java

@@ -0,0 +1,30 @@
+package com.daya.orchestra.accompany.player;
+
+/**
+ * Author by pq, Date on 2024/8/7.
+ */
+public abstract class BasePlayer {
+
+    public OnCompletionListener onListener;
+
+
+    public abstract void seekTo(int position);
+
+    public abstract long getCu();
+
+    public abstract long getT();
+
+    public abstract void stop();
+
+    public abstract void setSpeed(float speed);
+
+    public abstract void setVolume(float volume);
+
+    public abstract void release();
+
+    public abstract void play(boolean isMute, float speed, String path);
+
+    public void setOnCompletionListener(OnCompletionListener listener) {
+        this.onListener = listener;
+    }
+}

+ 216 - 0
accompany/src/main/java/com/daya/orchestra/accompany/player/CustomExoPlayer.java

@@ -0,0 +1,216 @@
+package com.daya.orchestra.accompany.player;
+
+import android.content.Context;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.cooleshow.base.utils.LOG;
+import com.daya.orchestra.accompany.common.Constants;
+import com.daya.orchestra.accompany.utils.MusicFileDownloadHelper;
+import com.google.android.exoplayer2.DefaultLoadControl;
+import com.google.android.exoplayer2.ExoPlayer;
+import com.google.android.exoplayer2.LoadControl;
+import com.google.android.exoplayer2.MediaItem;
+import com.google.android.exoplayer2.Player;
+import com.google.android.exoplayer2.SeekParameters;
+import com.google.android.exoplayer2.SimpleExoPlayer;
+
+import java.io.File;
+
+
+/**
+ * Author by pq, Date on 2024/8/6.
+ */
+public class CustomExoPlayer extends BasePlayer {
+    public static final String TAG = "CustomExoPlayer";
+
+    private ExoPlayer mExoPlayer;
+
+    private boolean hasPrepared;
+    private boolean isStoped = false;
+
+    private boolean isNeedMute = false;
+
+    private int prepareSeekPosition = -1;//此字段用于选段播放
+    private boolean isSeekCompleted;
+    private float speed = Constants.DEFAULT_PLAY_SPEED;
+
+    public CustomExoPlayer(Context context) {
+        initPlayer(context);
+    }
+
+    private void initPlayer(Context context) {
+        if (mExoPlayer == null) {
+            LoadControl loadControl = new DefaultLoadControl.Builder()
+//                    .setBufferDurationsMs(DefaultLoadControl.DEFAULT_MIN_BUFFER_MS / 4, DefaultLoadControl.DEFAULT_MAX_BUFFER_MS/4, DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS/4, DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS/4)
+                    .setBufferDurationsMs(DefaultLoadControl.DEFAULT_MIN_BUFFER_MS * 4, DefaultLoadControl.DEFAULT_MAX_BUFFER_MS * 4, DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS * 4, DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS * 4)
+                    .build();
+            mExoPlayer = new SimpleExoPlayer.Builder(context)
+                    .setLoadControl(loadControl).build();
+            // 将 LoadControl 对象应用到 ExoPlayer
+
+
+            mExoPlayer.addListener(new Player.Listener() {
+                @Override
+                public void onPlaybackStateChanged(int playbackState) {
+                    LOG.i("onPlaybackStateChanged:" + playbackState);
+                    if (playbackState == Player.STATE_ENDED) {
+                        if (onListener != null) {
+                            onListener.onCompletion();
+                        }
+                    } else if (playbackState == Player.STATE_READY) {
+                        start();
+                    }
+                }
+
+                @Override
+                public void onPositionDiscontinuity(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, int reason) {
+                    LOG.i("oldPosition:" + oldPosition.positionMs);
+                    LOG.i("newPosition:" + newPosition.positionMs);
+                }
+            });
+        }
+    }
+
+
+    @Override
+    public void play(boolean isMute, float speed, String path) {
+        hasPrepared = false; // 开始播放前讲Flag置为不可操作
+        isStoped = false; //
+        isSeekCompleted = false;
+        this.isNeedMute = isMute;
+        try {
+            MediaItem mediaItem = createMediaItem(path);
+            mExoPlayer.setMediaItem(mediaItem);
+            mExoPlayer.prepare();
+            mExoPlayer.setPlayWhenReady(false);
+            setVolume(isNeedMute ? 0 : 1.0f);
+            setSpeed(speed);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private MediaItem createMediaItem(String path) {
+        MediaItem mediaItem;
+        try {
+            String downloadSavePath = MusicFileDownloadHelper.getDownloadSavePath(path);
+            if (!TextUtils.isEmpty(downloadSavePath)) {
+                File file = new File(downloadSavePath);
+                if (file.exists()) {
+                    LOG.i("createMediaItem file:" + file.getAbsolutePath());
+                    mediaItem = MediaItem.fromUri(Uri.fromFile(file));
+                    return mediaItem;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        LOG.i("createMediaItem next file:" + path);
+        mediaItem = MediaItem.fromUri(Uri.parse(path));
+        return mediaItem;
+    }
+
+    private void start() {
+        if (isStoped) {
+            return;
+        }
+        // release()会释放player、将player置空,所以这里需要判断一下
+        if (null != mExoPlayer) {
+            if (prepareSeekPosition > 0 && !isSeekCompleted) {
+                seekTo(prepareSeekPosition);
+            } else {
+                mExoPlayer.play();
+            }
+        }
+    }
+
+    @Override
+    public void setSpeed(float speed) {
+        this.speed = speed;
+        mExoPlayer.setPlaybackSpeed(speed);
+    }
+
+    public float getSpeed() {
+        return speed;
+    }
+
+    @Override
+    public void setVolume(float volume) {
+        if (mExoPlayer != null) {
+            LOG.i("setVolume:" + volume + "hasPrepared:" + hasPrepared);
+            mExoPlayer.setVolume(volume);
+        }
+    }
+
+    @Override
+    public void seekTo(int position) {
+        if (null != mExoPlayer) {
+            mExoPlayer.setSeekParameters(SeekParameters.PREVIOUS_SYNC);
+            mExoPlayer.seekTo(position);
+            isSeekCompleted = true;
+        }
+    }
+
+    @Override
+    public long getCu() {
+        if (mExoPlayer != null) {
+            long currentPosition = mExoPlayer.getCurrentPosition();
+            long bufferedPosition = mExoPlayer.getBufferedPosition();
+            Log.i(TAG, "currentPosition:" + currentPosition);
+            Log.i(TAG, "bufferedPosition:" + bufferedPosition);
+            return currentPosition;
+        }
+        return -1;
+    }
+
+    @Override
+    public long getT() {
+        if (mExoPlayer != null) {
+            long duration = mExoPlayer.getDuration();
+            return duration;
+        }
+        return -1;
+    }
+
+    @Override
+    public void stop() {
+        if (mExoPlayer == null) {
+            return;
+        }
+        prepareSeekPosition = -1;
+        isStoped = true;
+        hasPrepared = false;
+        Log.i(TAG, "player to stop:" + hasPrepared + "-thread:" + Thread.currentThread().getName());
+        mExoPlayer.stop();
+    }
+
+    public int getPrepareSeekPosition() {
+        return prepareSeekPosition;
+    }
+
+    public long getExceptTargetPos(long cu) {
+        //用于选段评测流程 如果有选段快进则需要 按照快进开播播放的位置取
+        long targetPos = getPrepareSeekPosition() != -1 ? cu - getPrepareSeekPosition() : cu;
+        return targetPos;
+    }
+
+    public void setPrepareSeekPosition(int prepareSeekPosition) {
+        this.prepareSeekPosition = prepareSeekPosition;
+    }
+
+    @Override
+    public void release() {
+        try {
+            hasPrepared = false;
+            isStoped = true;
+            mExoPlayer.stop();
+            mExoPlayer.release();
+            mExoPlayer = null;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 226 - 0
accompany/src/main/java/com/daya/orchestra/accompany/player/CustomIJKPlayer.java

@@ -0,0 +1,226 @@
+//package com.daya.orchestra.accompany.player;
+//
+//import android.content.Context;
+//import android.media.AudioManager;
+//import android.net.Uri;
+//import android.util.Log;
+//import android.view.SurfaceHolder;
+//
+//import com.cooleshow.base.utils.LOG;
+//import com.daya.orchestra.accompany.common.Constants;
+//
+//import java.io.IOException;
+//
+//import tv.danmaku.ijk.media.player.IMediaPlayer;
+//import tv.danmaku.ijk.media.player.IjkMediaPlayer;
+//
+///**
+// * Author by pq, Date on 2023/5/11.
+// */
+//public class CustomIJKPlayer implements IjkMediaPlayer.OnErrorListener, IjkMediaPlayer.OnCompletionListener, IjkMediaPlayer.OnPreparedListener {
+//    public static final String TAG = "CustomPlayer";
+//    private Context mContext;
+//    IjkMediaPlayer mPlayer;
+//    private boolean hasPrepared;
+//    private boolean isStoped = false;
+//
+//    private boolean isNeedMute = false;
+//
+//    private int prepareSeekPosition = -1;//此字段用于选段播放
+//
+//    public CustomIJKPlayer() {
+//        initPlayer();
+//    }
+//
+//    private void initPlayer() {
+//        if (null == mPlayer) {
+//            mPlayer = new IjkMediaPlayer();
+//            mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+//            mPlayer.setOnErrorListener(this);
+//            mPlayer.setOnCompletionListener(this);
+//            mPlayer.setOnPreparedListener(this);
+//        }
+//    }
+//
+//    public void setOnCompletionListener(IjkMediaPlayer.OnCompletionListener listener) {
+//        if (mPlayer != null) {
+//            mPlayer.setOnCompletionListener(listener);
+//        }
+//    }
+//
+//    public void play(Context context, Uri dataSource) {
+//        hasPrepared = false; // 开始播放前讲Flag置为不可操作
+//        isStoped = false;
+//        initPlayer(); // 如果是第一次播放/player已经释放了,就会重新创建、初始化
+//        try {
+//            mPlayer.reset();
+//            mPlayer.setDataSource(context, dataSource); // 设置曲目资源
+//            mPlayer.prepareAsync(); // 异步的准备方法
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    public void play(boolean isMute, float speed,String path) {
+//        hasPrepared = false; // 开始播放前讲Flag置为不可操作
+//        isStoped = false; //
+//        this.isNeedMute = isMute;
+//        initPlayer(); // 如果是第一次播放/player已经释放了,就会重新创建、初始化
+//        try {
+//            mPlayer.reset();
+//            initOptions(speed);
+//            mPlayer.setDataSource(path); // 设置曲目资源
+//            mPlayer.prepareAsync(); // 异步的准备方法
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    private void initOptions(float speed) {
+//        if(speed != Constants.DEFAULT_PLAY_SPEED){
+//            mPlayer.setSpeed(speed);
+//            mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1);
+//        }
+//        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1);
+//        // 设置缓存策略
+//        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 1);
+//        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 5);
+//        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 4);
+//        //硬件加速
+//        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
+//        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
+//        // 调整同步设置
+//        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "sync", "audio");
+//    }
+//
+//    public int getPrepareSeekPosition() {
+//        return prepareSeekPosition;
+//    }
+//
+//    public long getExceptTargetPos(long cu) {
+//        //用于选段评测流程 如果有选段快进则需要 按照快进开播播放的位置取
+//        long targetPos = getPrepareSeekPosition() != -1 ? cu - getPrepareSeekPosition() : cu;
+//        return targetPos;
+//    }
+//
+//    public void setPrepareSeekPosition(int prepareSeekPosition) {
+//        this.prepareSeekPosition = prepareSeekPosition;
+//    }
+//
+//    public long getCu() {
+//        if (mPlayer != null) {
+//            long currentPosition = mPlayer.getCurrentPosition();
+//            return currentPosition;
+//        }
+//        return -1;
+//    }
+//
+//
+//    public long getT() {
+//        if (mPlayer != null) {
+//            long duration = mPlayer.getDuration();
+//            return duration;
+//        }
+//        return -1;
+//    }
+//
+//    public void start() {
+//        if (isStoped) {
+//            return;
+//        }
+//        // release()会释放player、将player置空,所以这里需要判断一下
+//        if (null != mPlayer && hasPrepared) {
+//            mPlayer.start();
+//            setVolume(isNeedMute ? 0f : 1f);
+//            if (prepareSeekPosition > 0) {
+//                seekTo(prepareSeekPosition);
+//            }
+//        }
+//    }
+//
+//    public void setVolume(float volume) {
+//        if (mPlayer != null) {
+//            LOG.i(TAG,"setVolume:" + volume + "hasPrepared:" + hasPrepared);
+//            mPlayer.setVolume(volume, volume);
+//        }
+//    }
+//
+//    public void pause() {
+//        if (null != mPlayer && hasPrepared) {
+//            mPlayer.pause();
+//        }
+//    }
+//
+//    public void seekTo(int position) {
+//        if (null != mPlayer && hasPrepared) {
+//            mPlayer.seekTo(position);
+//        }
+//    }
+//
+//    // 对于播放视频来说,通过设置SurfaceHolder来设置显示Surface。这个方法不需要判断状态、也不会改变player状态
+//    public void setDisplay(SurfaceHolder holder) {
+//        if (null != mPlayer) {
+//            mPlayer.setDisplay(holder);
+//        }
+//    }
+//
+//
+//    public void stop() {
+//        if (mPlayer == null) {
+//            return;
+//        }
+//        prepareSeekPosition = -1;
+//        isStoped = true;
+//        hasPrepared = false;
+//        Log.i(TAG, "player to stop:" + hasPrepared + "-thread:" + Thread.currentThread().getName());
+//        mPlayer.stop();
+//    }
+//
+//    @Override
+//    public void onCompletion(IMediaPlayer iMediaPlayer) {
+//        hasPrepared = false;
+//        LOG.i(TAG, "onCompletion");
+//        // 通知调用处,调用play()方法进行下一个曲目的播放
+//    }
+//
+//    @Override
+//    public boolean onError(IMediaPlayer iMediaPlayer, int i, int i1) {
+//        hasPrepared = false;
+//        return true;
+//    }
+//
+//    @Override
+//    public void onPrepared(IMediaPlayer iMediaPlayer) {
+//        hasPrepared = true; // 准备完成后回调到这里
+//        start();
+//    }
+//
+//    public void setSpeed(float speed) {
+//        Log.i(TAG, "setSpeed:" + speed);
+//        try {
+//            if (mPlayer != null) {
+//                if (speed > Constants.MAX_PLAY_SPEED) {
+//                    speed = Constants.MAX_PLAY_SPEED;
+//                }
+//                if (speed < Constants.MIN_PLAY_SPEED) {
+//                    speed = Constants.MIN_PLAY_SPEED;
+//                }
+//                mPlayer.setSpeed(speed);
+//                mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1);
+//            }
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
+//
+//
+//    public void release() {
+//        hasPrepared = false;
+//        isStoped = true;
+//        mPlayer.stop();
+//        mPlayer.release();
+//        mPlayer = null;
+//    }
+//
+//
+//}

+ 8 - 0
accompany/src/main/java/com/daya/orchestra/accompany/player/OnCompletionListener.java

@@ -0,0 +1,8 @@
+package com.daya.orchestra.accompany.player;
+
+/**
+ * Author by pq, Date on 2024/8/7.
+ */
+public interface OnCompletionListener {
+    void onCompletion();
+}

+ 0 - 226
accompany/src/main/java/com/daya/orchestra/accompany/presenter/CustomIJKPlayer.java

@@ -1,226 +0,0 @@
-package com.daya.orchestra.accompany.presenter;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import com.cooleshow.base.utils.LOG;
-import com.daya.orchestra.accompany.common.Constants;
-
-import java.io.IOException;
-
-import tv.danmaku.ijk.media.player.IMediaPlayer;
-import tv.danmaku.ijk.media.player.IjkMediaPlayer;
-
-/**
- * Author by pq, Date on 2023/5/11.
- */
-public class CustomIJKPlayer implements IjkMediaPlayer.OnErrorListener, IjkMediaPlayer.OnCompletionListener, IjkMediaPlayer.OnPreparedListener {
-    public static final String TAG = "CustomPlayer";
-    private Context mContext;
-    IjkMediaPlayer mPlayer;
-    private boolean hasPrepared;
-    private boolean isStoped = false;
-
-    private boolean isNeedMute = false;
-
-    private int prepareSeekPosition = -1;//此字段用于选段播放
-
-    public CustomIJKPlayer() {
-        initPlayer();
-    }
-
-    private void initPlayer() {
-        if (null == mPlayer) {
-            mPlayer = new IjkMediaPlayer();
-            mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
-            mPlayer.setOnErrorListener(this);
-            mPlayer.setOnCompletionListener(this);
-            mPlayer.setOnPreparedListener(this);
-        }
-    }
-
-    public void setOnCompletionListener(IjkMediaPlayer.OnCompletionListener listener) {
-        if (mPlayer != null) {
-            mPlayer.setOnCompletionListener(listener);
-        }
-    }
-
-    public void play(Context context, Uri dataSource) {
-        hasPrepared = false; // 开始播放前讲Flag置为不可操作
-        isStoped = false;
-        initPlayer(); // 如果是第一次播放/player已经释放了,就会重新创建、初始化
-        try {
-            mPlayer.reset();
-            mPlayer.setDataSource(context, dataSource); // 设置曲目资源
-            mPlayer.prepareAsync(); // 异步的准备方法
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void play(boolean isMute, float speed,String path) {
-        hasPrepared = false; // 开始播放前讲Flag置为不可操作
-        isStoped = false; //
-        this.isNeedMute = isMute;
-        initPlayer(); // 如果是第一次播放/player已经释放了,就会重新创建、初始化
-        try {
-            mPlayer.reset();
-            initOptions(speed);
-            mPlayer.setDataSource(path); // 设置曲目资源
-            mPlayer.prepareAsync(); // 异步的准备方法
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void initOptions(float speed) {
-        if(speed != Constants.DEFAULT_PLAY_SPEED){
-            mPlayer.setSpeed(speed);
-            mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1);
-        }
-        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1);
-        // 设置缓存策略
-        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 1);
-        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 5);
-        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 4);
-        //硬件加速
-        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
-        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
-        // 调整同步设置
-        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "sync", "audio");
-    }
-
-    public int getPrepareSeekPosition() {
-        return prepareSeekPosition;
-    }
-
-    public long getExceptTargetPos(long cu) {
-        //用于选段评测流程 如果有选段快进则需要 按照快进开播播放的位置取
-        long targetPos = getPrepareSeekPosition() != -1 ? cu - getPrepareSeekPosition() : cu;
-        return targetPos;
-    }
-
-    public void setPrepareSeekPosition(int prepareSeekPosition) {
-        this.prepareSeekPosition = prepareSeekPosition;
-    }
-
-    public long getCu() {
-        if (mPlayer != null) {
-            long currentPosition = mPlayer.getCurrentPosition();
-            return currentPosition;
-        }
-        return -1;
-    }
-
-
-    public long getT() {
-        if (mPlayer != null) {
-            long duration = mPlayer.getDuration();
-            return duration;
-        }
-        return -1;
-    }
-
-    public void start() {
-        if (isStoped) {
-            return;
-        }
-        // release()会释放player、将player置空,所以这里需要判断一下
-        if (null != mPlayer && hasPrepared) {
-            mPlayer.start();
-            setVolume(isNeedMute ? 0f : 1f);
-            if (prepareSeekPosition > 0) {
-                seekTo(prepareSeekPosition);
-            }
-        }
-    }
-
-    public void setVolume(float volume) {
-        if (mPlayer != null) {
-            LOG.i(TAG,"setVolume:" + volume + "hasPrepared:" + hasPrepared);
-            mPlayer.setVolume(volume, volume);
-        }
-    }
-
-    public void pause() {
-        if (null != mPlayer && hasPrepared) {
-            mPlayer.pause();
-        }
-    }
-
-    public void seekTo(int position) {
-        if (null != mPlayer && hasPrepared) {
-            mPlayer.seekTo(position);
-        }
-    }
-
-    // 对于播放视频来说,通过设置SurfaceHolder来设置显示Surface。这个方法不需要判断状态、也不会改变player状态
-    public void setDisplay(SurfaceHolder holder) {
-        if (null != mPlayer) {
-            mPlayer.setDisplay(holder);
-        }
-    }
-
-
-    public void stop() {
-        if (mPlayer == null) {
-            return;
-        }
-        prepareSeekPosition = -1;
-        isStoped = true;
-        hasPrepared = false;
-        Log.i(TAG, "player to stop:" + hasPrepared + "-thread:" + Thread.currentThread().getName());
-        mPlayer.stop();
-    }
-
-    @Override
-    public void onCompletion(IMediaPlayer iMediaPlayer) {
-        hasPrepared = false;
-        LOG.i(TAG, "onCompletion");
-        // 通知调用处,调用play()方法进行下一个曲目的播放
-    }
-
-    @Override
-    public boolean onError(IMediaPlayer iMediaPlayer, int i, int i1) {
-        hasPrepared = false;
-        return true;
-    }
-
-    @Override
-    public void onPrepared(IMediaPlayer iMediaPlayer) {
-        hasPrepared = true; // 准备完成后回调到这里
-        start();
-    }
-
-    public void setSpeed(float speed) {
-        Log.i(TAG, "setSpeed:" + speed);
-        try {
-            if (mPlayer != null) {
-                if (speed > Constants.MAX_PLAY_SPEED) {
-                    speed = Constants.MAX_PLAY_SPEED;
-                }
-                if (speed < Constants.MIN_PLAY_SPEED) {
-                    speed = Constants.MIN_PLAY_SPEED;
-                }
-                mPlayer.setSpeed(speed);
-                mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-
-    public void release() {
-        hasPrepared = false;
-        isStoped = true;
-        mPlayer.stop();
-        mPlayer.release();
-        mPlayer = null;
-    }
-
-
-}

+ 163 - 0
accompany/src/main/java/com/daya/orchestra/accompany/utils/MusicFileDownloadHelper.java

@@ -0,0 +1,163 @@
+package com.daya.orchestra.accompany.utils;
+
+import android.text.TextUtils;
+
+import com.cooleshow.base.data.net.RetrofitClientNoToken;
+import com.cooleshow.base.utils.EncryptUtils;
+import com.cooleshow.base.utils.FileUtils;
+import com.cooleshow.base.utils.LOG;
+import com.cooleshow.base.utils.MyFileUtils;
+import com.cooleshow.base.utils.Utils;
+import com.daya.orchestra.accompany.api.DownloadApi;
+import com.daya.orchestra.accompany.callback.ResultCallbackV2;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
+import io.reactivex.rxjava3.annotations.NonNull;
+import io.reactivex.rxjava3.core.Observable;
+import io.reactivex.rxjava3.core.ObservableEmitter;
+import io.reactivex.rxjava3.core.ObservableOnSubscribe;
+import io.reactivex.rxjava3.core.Observer;
+import io.reactivex.rxjava3.disposables.Disposable;
+import io.reactivex.rxjava3.schedulers.Schedulers;
+import okhttp3.ResponseBody;
+import retrofit2.Response;
+
+/**
+ * Author by pq, Date on 2024/8/12.
+ */
+public class MusicFileDownloadHelper {
+    public static final String BASE_PATH = MyFileUtils.getCacheDir2(Utils.getApp(), "musicFile");
+
+    private MusicFileDownloadHelper() {
+
+    }
+
+    private static class MusicFileDownloadHelperHolder {
+        public static MusicFileDownloadHelper mHelper = new MusicFileDownloadHelper();
+    }
+
+    public static MusicFileDownloadHelper getInstance() {
+        return MusicFileDownloadHelperHolder.mHelper;
+    }
+
+    public void download(String url, ResultCallbackV2<String> resultCallback) {
+        Observable.create(new ObservableOnSubscribe<String>() {
+                    @Override
+                    public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
+                        String downloadSaveTempPath = getDownloadSaveTempPath(url);
+                        FileUtils.createOrExistsFile(downloadSaveTempPath);
+                        File file = new File(downloadSaveTempPath);
+                        downloadFile(url, file, resultCallback);
+                        if (emitter != null) {
+                            emitter.onNext(getDownloadSavePath(url));
+                        }
+                    }
+                }).subscribeOn(Schedulers.newThread())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Observer<String>() {
+                    @Override
+                    public void onSubscribe(@NonNull Disposable d) {
+
+                    }
+
+                    @Override
+                    public void onNext(@NonNull String s) {
+                        if (resultCallback != null) {
+                            resultCallback.onSuccess(s);
+                        }
+                    }
+
+                    @Override
+                    public void onError(@NonNull Throwable e) {
+                        e.printStackTrace();
+                        if (resultCallback != null) {
+                            resultCallback.onFail(-1, "download error");
+                        }
+                    }
+
+                    @Override
+                    public void onComplete() {
+
+                    }
+                });
+    }
+
+    public static boolean checkFileIsExist(String url) {
+        String downloadSavePath = getDownloadSavePath(url);
+        File file = new File(downloadSavePath);
+        if (file.exists()) {
+            return true;
+        }
+        return false;
+    }
+
+    public String getDownloadSaveTempPath(String url) {
+        String fileEndSuffix = getFileType(url);
+        String fileName = EncryptUtils.encryptMD5ToString(url);
+        return BASE_PATH + File.separator + fileName + "_temp" + fileEndSuffix;
+    }
+
+    public static String getDownloadSavePath(String url) {
+        String fileType = getFileType(url);
+        String fileName = EncryptUtils.encryptMD5ToString(url);
+        String path = BASE_PATH + File.separator + fileName + fileType;
+        return path;
+    }
+
+    public static String getFileType(String url) {
+        int lastDot = url.lastIndexOf(".");
+        if (lastDot < 0) {
+            return "";
+        }
+        String fileType = url.substring(lastDot).toLowerCase();
+        return fileType;
+    }
+
+    private void downloadFile(String url, File file, ResultCallbackV2<String> resultCallback) {
+        if (TextUtils.isEmpty(url)) {
+            return;
+        }
+        try {
+            Response<ResponseBody> response = RetrofitClientNoToken.getInstance().getRetrofit().create(DownloadApi.class)
+                    .download(url).execute();
+            if (response == null || response.body() == null) {
+                return;
+            }
+            long total = response.body().contentLength();//需要下载的总大小
+            long current = 0;
+            InputStream inputStream = response.body().byteStream();
+            FileOutputStream fileOutputStream = new FileOutputStream(file);
+            byte[] bytes = new byte[1024];
+            int len = 0;
+            while ((len = inputStream.read(bytes)) != -1) {
+                fileOutputStream.write(bytes, 0, len);
+                fileOutputStream.flush();
+                current = current + len;
+                if (resultCallback != null) {
+                    int progressPercent = (int) ((current * 1.0f / total) * 100);
+                    resultCallback.onProgress(progressPercent);
+                }
+            }
+            replaceName(file);
+            fileOutputStream.flush();
+            fileOutputStream.close();
+            inputStream.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    private void replaceName(File file) {
+        String name = file.getName();
+        LOG.i("下载完成file:" + name);
+        String temp = name.replace("_temp", "");
+        LOG.i("替换之后file:" + temp);
+        FileUtils.rename(file, temp);
+    }
+}

+ 44 - 12
accompany/src/main/java/com/daya/orchestra/accompany/web/AccompanyActivity.java

@@ -33,9 +33,11 @@ import com.cooleshow.base.utils.helper.upload.UploadHelper;
 import com.cooleshow.usercenter.helper.UserHelper;
 import com.daya.orchestra.accompany.R;
 import com.daya.orchestra.accompany.callback.ResultCallback;
+import com.daya.orchestra.accompany.callback.ResultCallbackV2;
 import com.daya.orchestra.accompany.databinding.ActivityAccompanyBinding;
 import com.daya.orchestra.accompany.helper.AccompanyHelper;
 import com.daya.orchestra.accompany.helper.AccompanyPlayHelper;
+import com.daya.orchestra.accompany.utils.MusicFileDownloadHelper;
 import com.gyf.immersionbar.ImmersionBar;
 import com.tbruyelle.rxpermissions3.RxPermissions;
 import com.wonderkiln.camerakit.CameraKit;
@@ -170,7 +172,7 @@ public class AccompanyActivity extends BaseActivity<ActivityAccompanyBinding> {
                             } else if (TextUtils.equals(cameraKitEvent.getType(), CameraKitEvent.TYPE_START_RECORD_EVENT)) {
                                 if (cameraKitEvent instanceof CameraStartRecord) {
                                     CameraStartRecord recordEvent = (CameraStartRecord) cameraKitEvent;
-                                    startRecordRealTime = recordEvent.getTime() + 300;//真正录制时间还要更大一点,无法确定准确值,增加300
+                                    startRecordRealTime = recordEvent.getTime();//真正录制时间还要更大一点,无法确定准确值,增加300
                                 }
                             }
                         }
@@ -272,15 +274,36 @@ public class AccompanyActivity extends BaseActivity<ActivityAccompanyBinding> {
             }
 
             @Override
-            public void onDownloadAccompaniment(String accompanyUrl) {
-                AccompanyActivity.this.accompanimentUrl = accompanyUrl;
-                if (TextUtils.isEmpty(accompanimentUrl)) {
-//                    runOnUiThread(new Runnable() {
-//                        @Override
-//                        public void run() {
-//                            ToastUtil.getInstance().showShort("当前曲目无mp3伴奏");
-//                        }
-//                    });
+            public void onDownloadAccompaniment(JSONObject message) {
+                JSONObject content = message.optJSONObject("content");
+                if (content != null) {
+                    String accompanyMp3Url = content.optString("musicSrc");
+                    AccompanyActivity.this.accompanimentUrl = accompanyMp3Url;
+                    if (!TextUtils.isEmpty(accompanimentUrl)) {
+                        boolean b = MusicFileDownloadHelper.checkFileIsExist(accompanimentUrl);
+                        if (b) {
+                            sendCreateMusicPlayerMsg(message);
+                        } else {
+                            MusicFileDownloadHelper.getInstance().download(accompanyMp3Url, new ResultCallbackV2<String>() {
+                                @Override
+                                public void onSuccess(String s) {
+                                    LOG.i("download success:" + s);
+                                    sendCreateMusicPlayerMsg(message);
+                                }
+
+                                @Override
+                                public void onProgress(int progressPercent) {
+                                    LOG.i("download onProgress:" + progressPercent);
+                                }
+
+                                @Override
+                                public void onFail(int errorCode, String errorStr) {
+                                    LOG.i("download onFail:" + errorCode + "--" + errorStr);
+                                    sendCreateMusicPlayerMsg(message);
+                                }
+                            });
+                        }
+                    }
                 }
             }
 
@@ -337,6 +360,12 @@ public class AccompanyActivity extends BaseActivity<ActivityAccompanyBinding> {
         }
     }
 
+    private void sendCreateMusicPlayerMsg(JSONObject jsonObject) {
+        if (accompanyFragment != null) {
+            accompanyFragment.onSendMessage(jsonObject.toString());
+        }
+    }
+
     @SuppressLint("CheckResult")
     private void toStartCapture() {
         Observable.create(new ObservableOnSubscribe<Object>() {
@@ -366,8 +395,11 @@ public class AccompanyActivity extends BaseActivity<ActivityAccompanyBinding> {
 
     private int getVideoDelay() {
         if (startRecordRealTime != -1 && AccompanyPlayHelper.realPlayStartTime != -1) {
+            LOG.i("测试时间", "realPlayStartTime:" + AccompanyPlayHelper.realPlayStartTime);
+            LOG.i("测试时间", "startRecordRealTime:" + startRecordRealTime);
             int time = (int) (AccompanyPlayHelper.realPlayStartTime - startRecordRealTime);
-            LOG.i("pq", "视频录制消耗:" + time);
+            LOG.i("测试时间", "视频录制消耗:" + time);
+//            return Math.max(time, 0);
             return time;
         }
         return 0;
@@ -380,12 +412,12 @@ public class AccompanyActivity extends BaseActivity<ActivityAccompanyBinding> {
         }
         //此字段用于评测播放缓冲延迟以及设备延迟总和
         int customCacheForInt = UserHelper.getCustomCacheForInt(AccompanyPlayHelper.DELAY_FOR_CURRENT_CACHE_KEY, 0);
-//        customCacheForInt = -customCacheForInt;//这里要取反是因为录制在前 播放在后
         int evaluateDelay = customCacheForInt;
         String recordFilePath = MyFileUtils.getRecordFilePath();
         if (!TextUtils.isEmpty(filePath)) {
             recordFilePath = filePath;
             customCacheForInt = getVideoDelay();
+            LOG.i("视频延迟结果", "customCacheForInt:" + customCacheForInt);
         }
 
         ARouter.getInstance().build(RouterPath.MusicTuner.MUSIC_MERGE_PAGE)

+ 5 - 4
accompany/src/main/java/com/daya/orchestra/accompany/web/AccompanyFragment.java

@@ -1469,7 +1469,7 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyV2Bindin
          *
          * @param url
          */
-        void onDownloadAccompaniment(String url);
+        void onDownloadAccompaniment(JSONObject jsonObject);
 
         void openAdjustRecording(String recordId, String title, String coverImg,float speed);
     }
@@ -2064,9 +2064,6 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyV2Bindin
 
     @Override
     public void saveAccompanimentMp3(String accompanyUrl) {
-        if (onAccompanyListener != null) {
-            onAccompanyListener.onDownloadAccompaniment(accompanyUrl);
-        }
     }
 
     @Override
@@ -2123,6 +2120,10 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyV2Bindin
         if (mPlayHelper != null) {
             mPlayHelper.createMusicPlayer(message);
         }
+
+        if (onAccompanyListener != null) {
+            onAccompanyListener.onDownloadAccompaniment(message);
+        }
     }
 
     @Override

+ 13 - 9
ffmpegCmd/src/main/java/com/cooleshow/ffmpegcmd/util/FFmpegUtil.java

@@ -872,16 +872,20 @@ public class FFmpegUtil {
     }
 
     public static String[] changeAudioSpeed3(String inputPath, String outputPath, float speed) {
-        // atempo range [0.5, 100.0]
-        if (speed < 0.5) {
-            String s = buildAtempoFilters(speed);
-            String speedCmd = "ffmpeg -i -filter_complex [0:a]%s[a] -map [a]";
-            String format = String.format(Locale.getDefault(), speedCmd, s);
-            return insert(format.split(" "), 2, inputPath, outputPath);
+        if (speed > 100.0F) {
+            throw new IllegalArgumentException("audio speed range is from 0.5 to 100");
         } else {
-            String speedCmd = "ffmpeg -i -filter_complex [0:a]atempo=%.2f[a] -map [a]";
-            speedCmd = String.format(Locale.getDefault(), speedCmd, speed);
-            return insert(speedCmd.split(" "), 2, inputPath, outputPath);
+            String speedCmd;
+            if ((double)speed < 0.5) {
+                speedCmd = buildAtempoFilters((double)speed);
+                String command = "ffmpeg -i -filter:a %s -b:a 192k -ar 44100 -ac 2 -acodec pcm_s16le";
+                String format = String.format(Locale.getDefault(), command, speedCmd);
+                return insert(format.split(" "), 2, inputPath, outputPath);
+            } else {
+                speedCmd = "ffmpeg -i -filter:a atempo=%.2f -b:a 192k -ar 44100 -ac 2 -acodec pcm_s16le";
+                speedCmd = String.format(Locale.getDefault(), speedCmd, speed);
+                return insert(speedCmd.split(" "), 2, inputPath, outputPath);
+            }
         }
     }
 

+ 3 - 3
musicMerge/src/main/java/com/cooleshow/musicmerge/helper/MixHelper.java

@@ -272,8 +272,8 @@ public class MixHelper {
                             downloadAccompany(url, file, resultCallback);
                         }
                         resultCallback.onProgress(100);
-                        //变速
-                        String downloadChangeSpeedTempPath = getDownloadChangeSpeedPath(url, String.valueOf(speed), fileEndSuffix);
+                        //变速和转换为44100 双声道 wav文件
+                        String downloadChangeSpeedTempPath = getDownloadChangeSpeedPath(url, String.valueOf(speed), MyFileUtils.WAV_FILE_SUFFIX);
                         String s = checkChangeSpeedIfNeed(downloadSavePath, downloadChangeSpeedTempPath, speed);
                         if (emitter != null) {
                             emitter.onNext(s);
@@ -351,7 +351,7 @@ public class MixHelper {
 
     private String checkChangeSpeedIfNeed(String inputPath, String outPath, float speed) {
         FileUtils.delete(outPath);
-        String[] commands = FFmpegUtil.changeAudioSpeed2(inputPath, outPath, speed);
+        String[] commands = FFmpegUtil.changeAudioSpeed3(inputPath, outPath, speed);
         if (commands != null) {
             println(commands);
             int i = FFmpegCmd.executeSync(commands);

+ 10 - 4
musicMerge/src/main/java/com/cooleshow/musicmerge/player/CustomPlayer.java

@@ -170,10 +170,16 @@ public class CustomPlayer implements MediaPlayer.OnErrorListener, MediaPlayer.On
     }
 
     public void pause() {
-        if (null != mPlayer && hasPrepared) {
-            mPlayer.pause();
-            removeDelayPlayMsg();
-            removeProgressMsg();
+        try {
+            if (null != mPlayer && hasPrepared) {
+                if (mPlayer.isPlaying()) {
+                    mPlayer.pause();
+                }
+                removeDelayPlayMsg();
+                removeProgressMsg();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
         }
     }
 

+ 5 - 0
musicMerge/src/main/java/com/cooleshow/musicmerge/ui/MusicHandleActivity.java

@@ -303,6 +303,11 @@ public class MusicHandleActivity extends BaseMVPActivity<AcMusicHandleLayoutBind
                 //上传原始视频 以及 相关调节参数
                 toSaveDraft();
             }
+
+            @Override
+            public void pausePlay() {
+                MusicHandleActivity.this.pausePlay();
+            }
         });
         viewBinding.seekPlay.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
             @Override

+ 8 - 2
musicMerge/src/main/java/com/cooleshow/musicmerge/ui/MusicHandleActivity_.java

@@ -195,7 +195,7 @@ public class MusicHandleActivity_ extends BaseMVPActivity<AcMusicHandleLayoutBin
         mRecordId = getIntent().getStringExtra("recordId");
         worksId = getIntent().getStringExtra("worksId");
         imgCover = getIntent().getStringExtra("coverImg");
-        defaultDelay = Math.abs(getIntent().getIntExtra("defaultDelay", 0));
+        defaultDelay = getIntent().getIntExtra("defaultDelay", 0);
         evaluateDelay = Math.abs(getIntent().getIntExtra("evaluateDelay", 0));
         accompanyPlaySpeed = getIntent().getFloatExtra(MusicMergeConfig.SPEEDRATE_KEY, MergeConfig.DEFAULT_PLAY_SPEED);
         loadCover();
@@ -363,6 +363,11 @@ public class MusicHandleActivity_ extends BaseMVPActivity<AcMusicHandleLayoutBin
                 //上传原始视频 以及 相关调节参数
                 toSaveDraft();
             }
+
+            @Override
+            public void pausePlay() {
+                MusicHandleActivity_.this.pausePlay();
+            }
         });
         viewBinding.seekPlay.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
             @Override
@@ -1028,7 +1033,7 @@ public class MusicHandleActivity_ extends BaseMVPActivity<AcMusicHandleLayoutBin
         }
         setLoadingCancelable(false);
         showLoading("伴奏下载中");
-        MixHelper.getInstance().downloadAccompany(accompanyUrl, accompanyPlaySpeed, MyFileUtils.WAV_FILE_SUFFIX, new ResultCallback<String>() {
+        MixHelper.getInstance().downloadAccompany(accompanyUrl, accompanyPlaySpeed, MyFileUtils.MP3_FILE_SUFFIX, new ResultCallback<String>() {
             @Override
             public void onSuccess(String s) {
                 if (!checkActivityExist()) {
@@ -1176,6 +1181,7 @@ public class MusicHandleActivity_ extends BaseMVPActivity<AcMusicHandleLayoutBin
     }
 
     private void showSaveTipDialog() {
+        pausePlay();
         CommonConfirmDialog2 commonConfirmDialog = new CommonConfirmDialog2(this);
         commonConfirmDialog.setWidth(SizeUtils.dp2px(387));
         commonConfirmDialog.show();

+ 6 - 0
musicMerge/src/main/java/com/cooleshow/musicmerge/ui/MusicHandleSettingFragment.java

@@ -208,6 +208,9 @@ public class MusicHandleSettingFragment extends BaseFragment<FgMusicHandleSettin
     public void onClick(View view) {
         int id = view.getId();
         if (id == R.id.tv_save_works) {
+            if (mEventListener != null) {
+                mEventListener.pausePlay();
+            }
             showUploadCoverImgDialog();
 //            if (checkUploadCover()) {
 //                showUploadCoverImgDialog();
@@ -234,6 +237,7 @@ public class MusicHandleSettingFragment extends BaseFragment<FgMusicHandleSettin
 
         if (id == R.id.tv_save) {
             if (mEventListener != null) {
+                mEventListener.pausePlay();
                 mEventListener.saveDraft();
             }
 //            toCheckDownload(false);
@@ -499,6 +503,8 @@ public class MusicHandleSettingFragment extends BaseFragment<FgMusicHandleSettin
         void hideSetting();
 
         void saveDraft();
+
+        void pausePlay();
     }
 
     @Override