解决故事播放接口先播放在停止再播放死机问题
authorcheng <chengyf@zhihuishixun.com>
Sat, 13 Sep 2025 09:57:34 +0000 (17:57 +0800)
committercheng <chengyf@zhihuishixun.com>
Sat, 13 Sep 2025 09:57:34 +0000 (17:57 +0800)
code/sdk/application/wearable/fd230/nativeapp/nativeui/leiniao/src/ln_story_player_simple.cpp

index 4a0a22f..d8ffe7d 100644 (file)
@@ -62,6 +62,7 @@ typedef struct
 
 
 static bool ln_story_player_simple_play_file(ln_story_player_simple_t *impl, int file_index);
+static bool ln_story_player_simple_player_stat(ln_story_player_simple_t *impl, int file_index);
 
 /* ============================== 播放器回调类 ============================== */
 
@@ -306,24 +307,35 @@ static bool ln_story_player_simple_play_file(ln_story_player_simple_t *impl, int
     // 根据播放器状态进行处理
     if (player_state == PLAYER_STARTED || player_state == PLAYER_PLAYBACK_COMPLETE)
     {
-        printf("[SIMPLE_PLAYER] stopping and resetting player\n");
+        printf("[SIMPLE_PLAYER] stopping and resetting player before switching\n");
         impl->player->Stop();
         impl->player->Reset();
+        // 然后调用PlayerStat来重新播放
+        return ln_story_player_simple_player_stat(impl, file_index);
     }
     else if (player_state == PLAYER_PAUSED || player_state == PLAYER_IDLE)
     {
-        printf("[SIMPLE_PLAYER] resetting player\n");
+        printf("[SIMPLE_PLAYER] player is ready, calling PlayerStat\n");
         impl->player->Reset();
+        return ln_story_player_simple_player_stat(impl, file_index);
     }
     else
     {
-        printf("[SIMPLE_PLAYER] unknown state, forcing reset\n");
+        printf("[SIMPLE_PLAYER] unknown state, forcing reset and calling PlayerStat\n");
         impl->player->Stop();
         impl->player->Reset();
+        return ln_story_player_simple_player_stat(impl, file_index);
     }
-    
+}
+
+// 播放器状态设置和播放(类似PlayersModel::PlayerStat)
+static bool ln_story_player_simple_player_stat(ln_story_player_simple_t *impl, int file_index)
+{
+    printf("[SIMPLE_PLAYER] ln_story_player_simple_player_stat\n");
+    int32_t ret;
+
     // 设置回调函数
-    g_simple_player.player->SetPlayerCallback(g_player_callback);
+    impl->player->SetPlayerCallback(g_player_callback);
 
     // 设置音频源
     impl->source = std::make_shared<Source>(impl->file_paths[file_index], impl->header);
@@ -333,11 +345,11 @@ static bool ln_story_player_simple_play_file(ln_story_player_simple_t *impl, int
         return false;
     }
     
-    int32_t ret = impl->player->SetSource(*impl->source);
+    ret = impl->player->SetSource(*impl->source);
     if (ret != 0)
     {
         printf("[SIMPLE_PLAYER] set source failed: %d\n", ret);
-        impl->player->Reset();
+        impl->player->Reset();  // 只在SetSource失败时Reset
         return false;
     }
     
@@ -349,53 +361,57 @@ static bool ln_story_player_simple_play_file(ln_story_player_simple_t *impl, int
     if (ret != 0)
     {
         printf("[SIMPLE_PLAYER] prepare failed: %d\n", ret);
-        impl->player->Reset();
+        impl->player->Reset();  // 只在Prepare失败时Reset
         return false;
     }
     
-    // 设置音频会话和中断监听
+    // 设置音频会话和中断监听(只在第一次播放时申请)
     AudioManager &amInstance = AudioManager::GetInstance();
     
-    // 如果已经激活过音频中断,先清理
-    if (impl->is_activate_audio_interrupt && impl->interrupt && impl->sessionId != AUDIO_SESSION_ID_NONE)
+    if (!impl->is_activate_audio_interrupt)
     {
-        amInstance.DeactivateAudioInterrupt(*impl->interrupt);
-        impl->is_activate_audio_interrupt = false;
-        printf("[SIMPLE_PLAYER] previous audio interrupt deactivated\n");
-    }
-    
-    // 创建新的会话和中断
-    impl->sessionId = amInstance.MakeSessionId();
-    if (impl->sessionId == AUDIO_SESSION_ID_NONE)
-    {
-        printf("[SIMPLE_PLAYER] failed to create session\n");
-        impl->player->Reset();
-        return false;
+        // 创建新的会话和中断(只在第一次播放时创建)
+        impl->sessionId = amInstance.MakeSessionId();
+        if (impl->sessionId == AUDIO_SESSION_ID_NONE)
+        {
+            printf("[SIMPLE_PLAYER] failed to create session\n");
+            impl->player->Reset();
+            return false;
+        }
+        
+        impl->interruptListener = std::make_shared<SimplePlayerInterruptListener>(impl);
+        impl->interrupt = std::make_shared<AudioInterrupt>();
+        impl->interrupt->streamType = AUDIO_STREAM_MUSIC;
+        impl->interrupt->sessionID = impl->sessionId;
+        impl->interrupt->interruptListener = impl->interruptListener;
+        
+        if (amInstance.ActivateAudioInterrupt(*impl->interrupt) == INTERRUPT_FAILED)
+        {
+            printf("[SIMPLE_PLAYER] failed to activate audio interrupt\n");
+            impl->player->Reset();
+            return false;
+        }
+        
+        impl->is_activate_audio_interrupt = true;
+        printf("[SIMPLE_PLAYER] audio interrupt activated for first file\n");
     }
-    
-    impl->interruptListener = std::make_shared<SimplePlayerInterruptListener>(impl);
-    impl->interrupt = std::make_shared<AudioInterrupt>();
-    impl->interrupt->streamType = AUDIO_STREAM_MUSIC;
-    impl->interrupt->sessionID = impl->sessionId;
-    impl->interrupt->interruptListener = impl->interruptListener;
-    
-    if (amInstance.ActivateAudioInterrupt(*impl->interrupt) == INTERRUPT_FAILED)
+    else
     {
-        printf("[SIMPLE_PLAYER] failed to activate audio interrupt\n");
-        impl->player->Reset();
-        return false;
+        printf("[SIMPLE_PLAYER] reusing existing audio interrupt for file %d\n", file_index);
     }
     
-    impl->is_activate_audio_interrupt = true;
-    printf("[SIMPLE_PLAYER] audio interrupt activated for file %d\n", file_index);
-    
     // 设置音频会话ID
     ret = impl->player->SetAudioSessionId(impl->sessionId);
     if (ret != 0)
     {
         printf("[SIMPLE_PLAYER] SetAudioSessionId failed: %d\n", ret);
         impl->player->Reset();
-        amInstance.DeactivateAudioInterrupt(*impl->interrupt);
+        // 只在第一次播放失败时才清理音频中断
+        if (impl->is_activate_audio_interrupt)
+        {
+            amInstance.DeactivateAudioInterrupt(*impl->interrupt);
+            impl->is_activate_audio_interrupt = false;
+        }
         return false;
     }
     
@@ -406,7 +422,12 @@ static bool ln_story_player_simple_play_file(ln_story_player_simple_t *impl, int
         printf("[SIMPLE_PLAYER] play failed: %d\n", ret);
         impl->player->Stop();
         impl->player->Reset();
-        amInstance.DeactivateAudioInterrupt(*impl->interrupt);
+        // 只在第一次播放失败时才清理音频中断
+        if (impl->is_activate_audio_interrupt)
+        {
+            amInstance.DeactivateAudioInterrupt(*impl->interrupt);
+            impl->is_activate_audio_interrupt = false;
+        }
         return false;
     }
     
@@ -502,25 +523,71 @@ bool ln_story_player_simple_start(const char *story_dir)
     return true;
 }
 
-// 停止播放并清理资源
+// 停止播放
 void ln_story_player_simple_stop(void)
 {
-    printf("[SIMPLE_PLAYER] stopping playback\n");
+    printf("[SIMPLE_PLAYER] ln_story_player_simple_stop\n");
     
     g_simple_player.should_stop = true;
     g_simple_player.is_playing = false;
     
-    if (g_simple_player.player)
+    if (!g_simple_player.player)
+    {
+        printf("[SIMPLE_PLAYER] player is null, nothing to stop\n");
+        return;
+    }
+    
+    // 检查播放器状态
+    int32_t player_state;
+    int32_t ret = g_simple_player.player->GetPlayerState(player_state);
+    if (ret != 0)
+    {
+        printf("[SIMPLE_PLAYER] get player state failed: %d\n", ret);
+        // 即使获取状态失败,也要尝试清理
+    }
+    else
+    {
+        printf("[SIMPLE_PLAYER] current player state: %d\n", player_state);
+    }
+    
+    // 根据播放器状态进行处理(参考PlayersModel::PlayerStop)
+    if (player_state == PLAYER_STARTED || player_state == PLAYER_PLAYBACK_COMPLETE)
+    {
+        printf("[SIMPLE_PLAYER] stopping and resetting player\n");
+        ret = g_simple_player.player->Stop();
+        if (ret != 0)
+        {
+            printf("[SIMPLE_PLAYER] stop failed: %d\n", ret);
+        }
+        
+        ret = g_simple_player.player->Reset();
+        if (ret != 0)
+        {
+            printf("[SIMPLE_PLAYER] reset failed: %d\n", ret);
+        }
+    }
+    else if (player_state == PLAYER_PAUSED)
     {
+        printf("[SIMPLE_PLAYER] resetting paused player\n");
+        ret = g_simple_player.player->Reset();
+        if (ret != 0)
+        {
+            printf("[SIMPLE_PLAYER] reset failed: %d\n", ret);
+        }
+    }
+    else if (player_state == PLAYER_STOPPED)
+    {
+        printf("[SIMPLE_PLAYER] player already stopped\n");
+    }
+    else
+    {
+        printf("[SIMPLE_PLAYER] unknown state, forcing stop and reset\n");
         g_simple_player.player->Stop();
         g_simple_player.player->Reset();
     }
-    
     // 清理音频中断
     ClearActivateAudioInterrupt();
     
-    // 清理资源
-    CleanupResources();
     
     printf("[SIMPLE_PLAYER] playback stopped\n");
 }