瀏覽代碼

增加云教练跟练模式

Pq 2 年之前
父節點
當前提交
6276c3e45c

+ 2 - 0
BaseLibrary/src/main/java/com/cooleshow/base/common/WebApi.java

@@ -12,5 +12,7 @@ public class WebApi {
     public static final String SET_EVENT_TRACKING = "setEventTracking";
     //屏幕录屏限制开关
     public static final String LIMIT_SCREEN_RECORD = "limitScreenRecord";
+    //跟练模式
+    public static final String CLOUD_TOGGLE_FOLLOW = "cloudToggleFollow";
     public static final String WITHDRAW_TAG = "WITHDRAW";
 }

+ 67 - 0
musictuner/src/main/java/com/cooleshow/musictuner/utils/MusicTunerHelper.java

@@ -0,0 +1,67 @@
+package com.cooleshow.musictuner.utils;
+
+import be.tarsos.dsp.AudioDispatcher;
+import be.tarsos.dsp.AudioEvent;
+import be.tarsos.dsp.AudioProcessor;
+import be.tarsos.dsp.io.android.AudioDispatcherFactory;
+import be.tarsos.dsp.pitch.PitchDetectionHandler;
+import be.tarsos.dsp.pitch.PitchDetectionResult;
+import be.tarsos.dsp.pitch.PitchProcessor;
+
+/**
+ * Author by pq, Date on 2022/10/20.
+ */
+public class MusicTunerHelper {
+
+    private AudioDispatcher mDispatcher;
+    private Thread mThread;
+    private OnEventListener onEventListener;
+
+    public MusicTunerHelper(OnEventListener onEventListener) {
+        this.onEventListener = onEventListener;
+    }
+
+    public void start() {
+        if (mDispatcher == null) {
+            mDispatcher = AudioDispatcherFactory.fromDefaultMicrophone(22050, 1024, 0);
+        }
+        PitchDetectionHandler pdh = new PitchDetectionHandler() {
+            @Override
+            public void handlePitch(PitchDetectionResult res, AudioEvent e) {
+                final float pitchInHz = res.getPitch();
+                final float probability = res.getProbability();
+                if (onEventListener != null) {
+                    onEventListener.onResult(pitchInHz);
+                }
+            }
+        };
+        AudioProcessor p = new PitchProcessor(PitchProcessor.PitchEstimationAlgorithm.FFT_YIN, 22050, 1024, pdh);
+        mDispatcher.addAudioProcessor(p);
+        mThread = new Thread(mDispatcher, "Audio Dispatcher");
+        mThread.start();
+    }
+
+    public void stop() {
+        try {
+            if (mDispatcher != null) {
+                mDispatcher.stop();
+            }
+            if (mThread != null) {
+                mThread.interrupt();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void release() {
+        stop();
+        if (mDispatcher != null) {
+            mDispatcher = null;
+        }
+    }
+
+    public interface OnEventListener {
+        void onResult(float pitchInHz);
+    }
+}

+ 1 - 0
student/build.gradle

@@ -117,6 +117,7 @@ dependencies {
     implementation project(path: ':rong_im:common_im_ui')
     implementation project(path: ':live_teaching')
     implementation project(path: ':metronome')
+    implementation project(path: ':musictuner')
     implementation "com.alibaba:arouter-api:$rootProject.ext.android.arouter_api_version"
     kapt "com.alibaba:arouter-compiler:$rootProject.ext.android.arouter_api_version"
 

+ 50 - 1
student/src/main/java/com/cooleshow/student/ui/web/AccompanyFragment.java

@@ -62,6 +62,7 @@ import com.cooleshow.base.widgets.CommonDialog;
 import com.cooleshow.base.widgets.DialogUtil;
 import com.cooleshow.base.widgets.ViewConvertListener;
 import com.cooleshow.base.widgets.ViewHolder;
+import com.cooleshow.musictuner.utils.MusicTunerHelper;
 import com.cooleshow.student.BuildConfig;
 import com.cooleshow.student.api.APIService;
 import com.cooleshow.student.bean.alipay.AuthResult;
@@ -137,6 +138,7 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyBinding,
     private ShareAction mShareAction;
     private URI webSocketUri = URI.create("BuildConfig.BASE_STU_SOCKET_URL");
     private String mImageBase64;
+    private MusicTunerHelper mMusicTunerHelper;
 
     public static AccompanyFragment newInstance(String url) {
         AccompanyFragment fragment = new AccompanyFragment();
@@ -263,6 +265,7 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyBinding,
 
     @Override
     public void onSendMessage(String message) {
+        Log.i("accom", "message:" + message);
         if (webView != null) {
             webView.evaluateJavascript("postMessage('" + message + "')", new ValueCallback<String>() {
                 @Override
@@ -1320,7 +1323,9 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyBinding,
         EventBus.getDefault().unregister(this);
         MidiPlayerUtils.getInstance().stopPlay();
         UMShareAPI.get(mContext).release();
-
+        if (mMusicTunerHelper != null) {
+            mMusicTunerHelper.release();
+        }
     }
 
     @Override
@@ -1945,6 +1950,38 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyBinding,
         }
     }
 
+    @Override
+    public void cloudToggleFollow(String mode) {
+        new RxPermissions(this)
+                .request(Manifest.permission.RECORD_AUDIO)
+                .subscribe(permission -> {
+                    if (permission) {
+                        handleCloudFollow(mode);
+                    }
+                });
+    }
+
+    private void handleCloudFollow(String mode) {
+        if (mMusicTunerHelper == null) {
+            mMusicTunerHelper = new MusicTunerHelper(new MusicTunerHelper.OnEventListener() {
+                @Override
+                public void onResult(float pitchInHz) {
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            sendCloudToggleFollowResult(pitchInHz);
+                        }
+                    });
+                }
+            });
+        }
+        if (TextUtils.equals(mode, "start")) {
+            mMusicTunerHelper.start();
+        } else {
+            mMusicTunerHelper.stop();
+        }
+    }
+
     private void sendSavePicCallBack(String api, String result, String uuid) {
         JSONObject jsonObject = new JSONObject();
         JSONObject contentJson = new JSONObject();
@@ -2265,6 +2302,18 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyBinding,
         ShareHelper.parseShareContactData(mImageBase64, data);
     }
 
+    private void sendCloudToggleFollowResult(float result) {
+        try {
+            JSONObject jsonObject = new JSONObject();
+            JSONObject contentJson = new JSONObject();
+            jsonObject.put("api", "cloudFollowTime");
+            contentJson.put("frequency", result);
+            jsonObject.put("content", contentJson);
+            onSendMessage(jsonObject.toString());
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+    }
 
     /**
      * 发送支付结果

+ 22 - 4
student/src/main/java/com/cooleshow/student/widgets/helper/JsInterfaceAccomPanyUtils.java

@@ -57,11 +57,11 @@ public class JsInterfaceAccomPanyUtils extends Object {
                             .withString(UserConstants.PHONE_NUM_KEY, UserHelper.getUserPhone())
                             .navigation();
                     activity.finish();
-                }  else if("cloudLoading".equals(api)){
+                } else if ("cloudLoading".equals(api)) {
                     if (onListener != null) {
                         onListener.cloudLoading(jsonObject);
                     }
-                }else if ("openConversationActivity".equals(api)) {
+                } else if ("openConversationActivity".equals(api)) {
                     JSONObject contentBean = jsonObject.getJSONObject("content");
                     if (null != contentBean) {
                         RongIM.getInstance().startPrivateChat(activity, contentBean.getString("userId"), contentBean.getString("name"));
@@ -312,7 +312,7 @@ public class JsInterfaceAccomPanyUtils extends Object {
                 if ("savePicture".equalsIgnoreCase(api)) {
                     JSONObject content = jsonObject.getJSONObject("content");
                     if (onListener != null) {
-                        onListener.savePicture(content.getString("base64"),content.getString("uuid"));
+                        onListener.savePicture(content.getString("base64"), content.getString("uuid"));
                     }
                 }
 
@@ -326,6 +326,7 @@ public class JsInterfaceAccomPanyUtils extends Object {
                     return;
                 }
 
+
                 if (TextUtils.equals(WebApi.LIMIT_SCREEN_RECORD, api)) {
                     //录屏截屏事件控制
                     JSONObject content = jsonObject.getJSONObject("content");
@@ -340,6 +341,15 @@ public class JsInterfaceAccomPanyUtils extends Object {
                     }
                     return;
                 }
+
+                //跟练模式
+                if (TextUtils.equals(WebApi.CLOUD_TOGGLE_FOLLOW, api)) {
+                    JSONObject content = jsonObject.getJSONObject("content");
+                    if (onListener != null) {
+                        onListener.cloudToggleFollow(content.getString("state"));
+                    }
+                    return;
+                }
             } catch (Exception e) {
 
             }
@@ -584,6 +594,7 @@ public class JsInterfaceAccomPanyUtils extends Object {
          * @param message
          */
         void cloudDestroy(JSONObject message);
+
         /**
          * 进入直播间
          *
@@ -608,11 +619,18 @@ public class JsInterfaceAccomPanyUtils extends Object {
          * @param payInfo
          */
         void paymentOrder(String orderNo, String payChannel, String payInfo);
+
         /**
          * 保存图片
+         *
          * @param base64
          */
-        void savePicture(String base64,String uuid);
+        void savePicture(String base64, String uuid);
+
+        /**
+         * 跟练模式
+         */
+        void cloudToggleFollow(String mode);
     }
 
 }

+ 1 - 0
teacher/build.gradle

@@ -123,6 +123,7 @@ dependencies {
     implementation project(path: ':rong_im:live')
     implementation project(path: ':rong_im:common_im_ui')
     implementation project(path: ':live_teaching')
+    implementation project(path: ':musictuner')
     implementation "com.alibaba:arouter-api:$rootProject.ext.android.arouter_api_version"
     kapt "com.alibaba:arouter-compiler:$rootProject.ext.android.arouter_api_version"
     //融云美颜库 //cn.rongcloud.sdk:rtc_lib:5.2.1

+ 51 - 1
teacher/src/main/java/com/cooleshow/teacher/ui/web/AccompanyFragment.java

@@ -62,6 +62,7 @@ import com.cooleshow.base.widgets.CommonDialog;
 import com.cooleshow.base.widgets.DialogUtil;
 import com.cooleshow.base.widgets.ViewConvertListener;
 import com.cooleshow.base.widgets.ViewHolder;
+import com.cooleshow.musictuner.utils.MusicTunerHelper;
 import com.cooleshow.teacher.BuildConfig;
 import com.cooleshow.teacher.api.APIService;
 import com.cooleshow.teacher.bean.alipay.AuthResult;
@@ -140,6 +141,7 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyBinding,
     private ShareAction mShareAction;
     private URI webSocketUri = URI.create("BuildConfig.BASE_STU_SOCKET_URL");
     private String mImageBase64;
+    private MusicTunerHelper mMusicTunerHelper;
 
     public static AccompanyFragment newInstance(String url) {
         AccompanyFragment fragment = new AccompanyFragment();
@@ -268,6 +270,7 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyBinding,
 
     @Override
     public void onSendMessage(String message) {
+        Log.i("acc","message:"+message);
         if (webView != null) {
             webView.evaluateJavascript("postMessage('" + message + "')", new ValueCallback<String>() {
                 @Override
@@ -1324,7 +1327,9 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyBinding,
         EventBus.getDefault().unregister(this);
         MidiPlayerUtils.getInstance().stopPlay();
         UMShareAPI.get(mContext).release();
-
+        if (mMusicTunerHelper != null) {
+            mMusicTunerHelper.release();
+        }
     }
 
     @Override
@@ -1940,6 +1945,51 @@ public class AccompanyFragment extends BaseMVPFragment<FragmentAccompanyBinding,
     }
 
     @Override
+    public void cloudToggleFollow(String mode) {
+        new RxPermissions(this)
+                .request(Manifest.permission.RECORD_AUDIO)
+                .subscribe(permission -> {
+                    if (permission) {
+                        handleCloudFollow(mode);
+                    }
+                });
+    }
+
+    private void handleCloudFollow(String mode) {
+        if (mMusicTunerHelper == null) {
+            mMusicTunerHelper = new MusicTunerHelper(new MusicTunerHelper.OnEventListener() {
+                @Override
+                public void onResult(float pitchInHz) {
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            sendCloudToggleFollowResult(pitchInHz);
+                        }
+                    });
+                }
+            });
+        }
+        if (TextUtils.equals(mode, "start")) {
+            mMusicTunerHelper.start();
+        } else {
+            mMusicTunerHelper.stop();
+        }
+    }
+
+    private void sendCloudToggleFollowResult(float result) {
+        try {
+            JSONObject jsonObject = new JSONObject();
+            JSONObject contentJson = new JSONObject();
+            jsonObject.put("api", "cloudFollowTime");
+            contentJson.put("frequency", result);
+            jsonObject.put("content", contentJson);
+            onSendMessage(jsonObject.toString());
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
     public void savePicture(String base64, String uuid) {
         try {
             com.cooleshow.base.utils.FileUtils.saveBase64ImgToLocalFile(base64);

+ 14 - 0
teacher/src/main/java/com/cooleshow/teacher/widgets/helper/JsInterfaceAccomPanyUtils.java

@@ -337,6 +337,15 @@ public class JsInterfaceAccomPanyUtils extends Object {
                     }
                     return;
                 }
+
+                //跟练模式
+                if (TextUtils.equals(WebApi.CLOUD_TOGGLE_FOLLOW, api)) {
+                    JSONObject content = jsonObject.getJSONObject("content");
+                    if (onListener != null) {
+                        onListener.cloudToggleFollow(content.getString("state"));
+                    }
+                    return;
+                }
             } catch (Exception e) {
 
             }
@@ -611,6 +620,11 @@ public class JsInterfaceAccomPanyUtils extends Object {
          * @param base64
          */
         void savePicture(String base64,String uuid);
+
+        /**
+         * 跟练模式
+         */
+        void cloudToggleFollow(String mode);
     }
 
 }