Преглед изворни кода

修复道理鱼播放问题

chendeben пре 6 месеци
родитељ
комит
712929b6f8

+ 4 - 4
entry/oh-package-lock.json5

@@ -14,20 +14,20 @@
     "@ohos/ijkplayer@../ijkplayer": {
       "name": "@ohos/ijkplayer",
       "version": "2.0.5",
-      "resolved": "",
+      "resolved": "../ijkplayer",
       "registryType": "local"
     },
     "@tencent/wechat_open_sdk@1.0.0": {
-      "name": "",
+      "name": "@tencent/wechat_open_sdk",
       "version": "1.0.0",
       "integrity": "sha512-rB1bWPTeMEir10+RguSlURf2ji/m7Xs0exh+EdRUEYhwKqnxMGylaASjX/A1nqZM1KBmx5+MVwt9DayTReP3mA==",
-      "resolved": "https://repo.harmonyos.com/ohpm/@tencent/wechat_open_sdk/-/wechat_open_sdk-1.0.0.har",
+      "resolved": "https://ohpm.openharmony.cn/ohpm/@tencent/wechat_open_sdk/-/wechat_open_sdk-1.0.0.har",
       "registryType": "ohpm"
     },
     "@types/libijkplayer_audio_napi.so@../ijkplayer/src/main/cpp/types/ijkplayer_audio_napi": {
       "name": "@types/libijkplayer_audio_napi.so",
       "version": "2.0.3-rc.3",
-      "resolved": "",
+      "resolved": "../ijkplayer/src/main/cpp/types/ijkplayer_audio_napi",
       "registryType": "local"
     }
   }

+ 2 - 1
entry/src/main/ets/common/network/DaoLiYuApi.ets

@@ -386,7 +386,8 @@ export class DaoLiYuApi {
     const auth = await this.ensureAuth(account);
     const baseUrl = this.buildBaseUrl(account);
     const token = encodeURIComponent(auth.token);
-    return `${baseUrl}/api/tracks/${encodeURIComponent(trackId)}/stream?token=${token}`;
+    // original=1 返回原始音频流,更有利于播放器按 Range 进行定位。
+    return `${baseUrl}/api/tracks/${encodeURIComponent(trackId)}/stream?token=${token}&original=1`;
   }
 
   buildImageUrl(account: WebDavAccount, path?: string): string | undefined {

+ 16 - 2
entry/src/main/ets/view/LocalMusic.ets

@@ -10982,6 +10982,9 @@ export struct LocalMusic {
           .layoutWeight(1)
           .enabled(this.slideEnable)
           .onChange((value: number, mode: SliderChangeMode) => {
+            if (mode !== 2) {
+              return
+            }
             if(this.isSeekTo)
               return
             this.isSeekTo = true;
@@ -11269,7 +11272,9 @@ export struct LocalMusic {
         .showTips(true)
         .enabled(this.slideEnable)
         .onChange((value: number, mode: SliderChangeMode) => {
-          // if (mode == 2) {
+          if (mode !== 2) {
+            return
+          }
 
           this.isSeekTo = true;
           this.mDestroyPage = false;
@@ -15480,6 +15485,10 @@ export struct LocalMusic {
     if (this.castControllerWrapper && this.isCastPlaying) {
       try {
         let seekPos = Number.parseInt(value);
+        const duration = this.getActiveDuration();
+        if (duration > 0) {
+          seekPos = Math.max(0, Math.min(seekPos, duration - 200));
+        }
         this.isSeekTo = true;
         Logger.info('heanup seekTo', `投播模式seek到: ${seekPos}ms, 当前时长: ${this.duration}ms`);
 
@@ -15495,8 +15504,13 @@ export struct LocalMusic {
       }
     } else {
       // 本地播放器模式
+      let seekPos = Number.parseInt(value);
+      const duration = this.getActiveDuration();
+      if (duration > 0) {
+        seekPos = Math.max(0, Math.min(seekPos, duration - 200));
+      }
       this.isSeekTo = true
-      this.mIjkMediaPlayer.seekTo(value);
+      this.mIjkMediaPlayer.seekTo(seekPos + "");
       this.setProgress()
       this.isSeekTo = false
     }

+ 2 - 1
ijkplayer/oh-package-lock.json5

@@ -1,6 +1,7 @@
 {
   "meta": {
-    "stableOrder": true
+    "stableOrder": true,
+    "enableUnifiedLockfile": false
   },
   "lockfileVersion": 3,
   "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",

+ 46 - 33
ijkplayer/src/main/cpp/ijkplayer/ff_ffplay.c

@@ -3432,52 +3432,65 @@ static int read_thread(void *arg)
             ffp_toggle_buffering(ffp, 1);
             ffp_notify_msg3(ffp, FFP_MSG_BUFFERING_UPDATE, 0, 0);
 
-            // Workaround for ASF/WMA seek crash (FFmpeg ff_seek_frame_binary uninitialized variable issue)
-            // The FFmpeg libavformat has a bug in ff_seek_frame_binary with uninitialized pos_min/pos_max
-            // For ASF format, we completely disable seek to prevent crash
             int seek_flags = is->seek_flags;
 
-            // Debug: print format name to diagnose ASF detection
             const char *format_name = (ic->iformat && ic->iformat->name) ? ic->iformat->name : "unknown";
             av_log(ffp, AV_LOG_WARNING, "heanup seek: format_name=%s\n", format_name);
 
-            // Check for ASF format (WMA files use ASF container)
-            // Also check for "asf_o" which is the output variant
             int is_asf_format = (ic->iformat && ic->iformat->name &&
                                  (strcmp(ic->iformat->name, "asf") == 0 ||
                                   strcmp(ic->iformat->name, "asf_o") == 0 ||
                                   strstr(ic->iformat->name, "asf") != NULL));
+            int is_flac_format = (ic->iformat && ic->iformat->name &&
+                                  strstr(ic->iformat->name, "flac") != NULL);
+            int use_safe_byte_seek = is_asf_format;
+
+            if (use_safe_byte_seek) {
+                // Avoid avformat_seek_file for fragile formats on network streams.
+                const char *safe_seek_name = is_flac_format ? "FLAC" : "ASF";
+                if (!ic->pb || !(ic->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
+                    av_log(ffp, AV_LOG_WARNING, "heanup: %s stream is not byte-seekable, reject seek\n", safe_seek_name);
+                    ret = -1;
+                } else {
+                    int64_t file_size = avio_size(ic->pb);
+                    int64_t duration = ic->duration;
+                    int64_t bounded_target = seek_target;
+
+                    if (duration > 0) {
+                        if (bounded_target < 0)
+                            bounded_target = 0;
+                        if (bounded_target > duration)
+                            bounded_target = duration;
+                    }
 
-            if (is_asf_format) {
-                // ASF/WMA format: use alternative seek method to avoid ff_seek_frame_binary crash
-                // The crash occurs because ff_seek_frame_binary has uninitialized pos_min/pos_max
-                // Try using AVSEEK_FLAG_BYTE to force byte-based seeking instead of timestamp-based
-                av_log(ffp, AV_LOG_WARNING, "heanup: ASF format, trying byte-based seek\n");
-
-                // Calculate byte position based on duration and file size
-                int64_t file_size = avio_size(ic->pb);
-                int64_t duration = ic->duration;
-
-                if (file_size > 0 && duration > 0) {
-                    // Convert seek_target (in AV_TIME_BASE) to byte position
-                    int64_t byte_pos = av_rescale(seek_target, file_size, duration);
-                    av_log(ffp, AV_LOG_WARNING, "heanup: ASF byte seek: target=%lld, file_size=%lld, duration=%lld, byte_pos=%lld\n",
-                           (long long)seek_target, (long long)file_size, (long long)duration, (long long)byte_pos);
-
-                    // Use av_seek_frame with AVSEEK_FLAG_BYTE for byte-based seeking
-                    ret = av_seek_frame(ic, -1, byte_pos, AVSEEK_FLAG_BYTE | AVSEEK_FLAG_BACKWARD);
-
-                    if (ret < 0) {
-                        av_log(ffp, AV_LOG_WARNING, "heanup: ASF byte seek failed, ret=%d\n", ret);
+                    if (file_size > 1 && duration > 0 && bounded_target >= 0) {
+                        int64_t byte_pos = av_rescale_rnd(bounded_target, file_size - 1, duration, AV_ROUND_DOWN);
+                        if (byte_pos < 0)
+                            byte_pos = 0;
+                        if (byte_pos >= file_size)
+                            byte_pos = file_size - 1;
+
+                        av_log(ffp, AV_LOG_WARNING,
+                               "heanup: %s safe byte seek: target=%lld, bounded_target=%lld, file_size=%lld, duration=%lld, byte_pos=%lld\n",
+                               safe_seek_name, (long long)seek_target, (long long)bounded_target,
+                               (long long)file_size, (long long)duration, (long long)byte_pos);
+                        ret = av_seek_frame(ic, -1, byte_pos, AVSEEK_FLAG_BYTE | AVSEEK_FLAG_BACKWARD);
+                        if (ret < 0) {
+                            av_log(ffp, AV_LOG_WARNING, "heanup: %s safe byte seek failed, ret=%d\n", safe_seek_name, ret);
+                        }
+                    } else {
+                        av_log(ffp, AV_LOG_WARNING,
+                               "heanup: %s cannot calculate safe byte position, file_size=%lld, duration=%lld, target=%lld\n",
+                               safe_seek_name, (long long)file_size, (long long)duration, (long long)seek_target);
+                        ret = -1;
                     }
-                } else {
-                    av_log(ffp, AV_LOG_WARNING, "heanup: ASF cannot calculate byte position, file_size=%lld, duration=%lld\n",
-                           (long long)file_size, (long long)duration);
-                    ret = -1;
                 }
-                // Don't continue here - let the code below handle flush if seek succeeded
             } else {
-                // Normal format: use avformat_seek_file
+                if (is_flac_format) {
+                    // FLAC is VBR-like for byte-position mapping; forcing byte-seek can land mid-frame.
+                    seek_flags &= ~AVSEEK_FLAG_BYTE;
+                    seek_flags |= AVSEEK_FLAG_ANY;
+                }
                 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, seek_flags);
             }
 

+ 2 - 2
oh-package.json5

@@ -13,7 +13,6 @@
   "version": "2.0.5",
   "dependencies": {
     "@pura/harmony-utils": "^1.2.4",
-    "@pura/harmony-dialog": "^1.0.6",
     "@chinalike/popup": "^0.0.7",
     "@seagazer/cclyric": "file:./lib",
     "@cashier_alipay/cashiersdk": "^15.8.32",
@@ -27,7 +26,8 @@
     "@nutpi/chinese_transverter": "^1.0.4",
     "@abner/track": "^1.0.2",
     "@liuzhosoft/ftp4h": "^2.0.0",
-    "@webabcd/harmony-httpserver": "^1.0.0"
+    "@webabcd/harmony-httpserver": "^1.0.0",
+    "@pura/harmony-dialog": "^1.1.8"
   },
   "dynamicDependencies": {}
 }