Эх сурвалжийг харах

修复部分文件播放异常

chendeben 7 сар өмнө
parent
commit
015061f62a

+ 10 - 3
entry/src/main/ets/common/network/BaiduPanClient.ets

@@ -282,7 +282,8 @@ export async function ensureAudioStreamReady(
   path: string,
   type: string = BaiduConstants.STREAMING_AUDIO_TYPE,
   maxRetries: number = 5,
-  retryDelayMs: number = 1000
+  retryDelayMs: number = 1000,
+  requireEndlist: boolean = false
 ): Promise<void> {
   if (!accessToken) {
     throw new Error('缺少百度网盘access_token');
@@ -314,8 +315,14 @@ export async function ensureAudioStreamReady(
       });
       const body = parseResponseBody(response);
       if (response.responseCode === 200 && typeof body === 'string' && body.includes('#EXTM3U')) {
-        Logger.info(TAG, `百度音频流准备就绪 attempt=${attempt + 1}`);
-        return;
+        const hasEndlist = body.includes('#EXT-X-ENDLIST');
+        if (!requireEndlist || hasEndlist) {
+          Logger.info(TAG, `百度音频流准备就绪 attempt=${attempt + 1} endlist=${hasEndlist}`);
+          return;
+        }
+        Logger.info(TAG, `百度音频流未完成转码,等待#EXT-X-ENDLIST attempt=${attempt + 1}`);
+        await delay(retryDelayMs);
+        continue;
       }
       let errno = 0;
       try {

+ 1 - 2
entry/src/main/ets/common/util/RemoteDriveManager.ets

@@ -618,7 +618,6 @@ export class RemoteDriveManager {
 
     if (currentSong.type === CommonConstants.TYPE_BAIDU) {
       headers.set('User-Agent', BaiduConstants.STREAMING_USER_AGENT);
-      headers.set('Host', 'pan.baidu.com');
       headers.set('Accept', '*/*');
       headers.set('Connection', 'Keep-Alive');
       headers.set('Referer', 'https://pan.baidu.com/disk/home');
@@ -2204,7 +2203,7 @@ export class RemoteDriveManager {
     let streamUrl = urlWithToken;
     if (remotePath) {
       try {
-        await ensureAudioStreamReady(accessToken, remotePath);
+        await ensureAudioStreamReady(accessToken, remotePath, BaiduConstants.STREAMING_AUDIO_TYPE, 240, 1000, true);
         streamUrl = buildAudioStreamingUrl(accessToken, remotePath);
         Logger.info(TAG, `百度网盘文件信息获取成功: fsId=${fsId}, size=${meta.size}, streamUrl=${streamUrl}`);
       } catch (streamError) {

+ 18 - 4
entry/src/main/ets/view/LocalMusic.ets

@@ -697,9 +697,14 @@ async function setVideoUrlForSong(song: VideoItem, options?: MetadataExtractionO
       if (fileExists) {
         const fileSize = await FileManager.getFileSize(cachedPath.cachePath);
         if (fileSize > 0) {
-          Logger.info(TAG, `百度网盘文件已缓存: ${cachedPath.cachePath}`);
-          void scheduleMetadataExtractionFromCache(song, cachedPath.cachePath, metadataOptions, song.videoSize);
-          return cachedPath.cachePath;
+          if (song.videoSize > 0 && fileSize < song.videoSize * 0.9) {
+            Logger.warn(TAG, `百度网盘缓存文件不完整,准备删除重试: ${cachedPath.cachePath}, size=${fileSize}, expect=${song.videoSize}`);
+            await FileManager.deleteFile(cachedPath.cachePath);
+          } else {
+            Logger.info(TAG, `百度网盘文件已缓存: ${cachedPath.cachePath}`);
+            void scheduleMetadataExtractionFromCache(song, cachedPath.cachePath, metadataOptions, song.videoSize);
+            return cachedPath.cachePath;
+          }
         }
       }
 
@@ -13672,7 +13677,9 @@ export struct LocalMusic {
                 expectDataType: http.HttpDataType.STRING,
                 header: {
                   'User-Agent': BaiduConstants.STREAMING_USER_AGENT,
-                  'Host': 'pan.baidu.com'
+                  'Host': 'pan.baidu.com',
+                  'Referer': 'https://pan.baidu.com/disk/home',
+                  'Accept-Encoding': 'identity'
                 }
               });
               if (response.responseCode !== 200 || typeof response.result !== 'string') {
@@ -13725,6 +13732,13 @@ export struct LocalMusic {
           console.info("onecold preparedDuration--" + preparedDuration)
           if (preparedDuration > 0) {
             applyDuration(preparedDuration);
+            if (this.videoUrl.includes('method=streaming') && isBaiduType(this.currentSong?.type ?? -1)) {
+              const durationMs = await fetchBaiduM3u8Duration(this.videoUrl);
+              if (durationMs > 0 && Math.abs(durationMs - preparedDuration) > 1000) {
+                Logger.info(TAG, `heanup 使用M3U8时长覆盖播放器时长: ${preparedDuration}ms -> ${durationMs}ms`);
+                applyDuration(durationMs);
+              }
+            }
           } else {
             fetchDurationFallback();
           }

+ 8 - 0
entry/src/main/ets/view/NavidromePage.ets

@@ -348,6 +348,7 @@ export struct NavidromePage {
       this.songNextStart = 0;
       this.artistNextStart = 0;
       this.albumNextStart = 0;
+      this.playlistNextStart = null;
       await Promise.all([
         this.loadNextJellyfinSongPage(account, ticket),
         this.loadNextJellyfinArtistPage(account, ticket),
@@ -378,6 +379,7 @@ export struct NavidromePage {
       this.songNextStart = 0;
       this.artistNextStart = 0;
       this.albumNextStart = 0;
+      this.playlistNextStart = null;
       await Promise.all([
         this.loadNextEmbySongPage(account, ticket),
         this.loadNextEmbyArtistPage(account, ticket),
@@ -2076,6 +2078,12 @@ export struct NavidromePage {
       throw new Error('媒体库账号不可用');
     }
     if (!this.isNavidromeAccount(account)) {
+      if (this.filterType === NavFilterType.Playlist) {
+        this.filterSongs = [];
+        this.isFilterLoading = false;
+        ToastUtil.showToast('当前媒体库不支持歌单');
+        return;
+      }
       let restSongs: NavidromeRestSong[] = [];
       if (this.filterType === NavFilterType.Artist) {
         if (this.isJellyfinAccount(account)) {