Commit 08de2824604ab6c1e90a981e5a5a1f954ed4ddc8

Authored by yibo
1 parent 8c3c082a

fix(lifelog): 语音列表播放按 audioStartMs 切片,对齐文字

块级管线下一个块的所有 turn 共用「块完整录音」.opus,靠 audioStartMs 偏移切片。
人物档案「语音」列表 + 时间轴段操作面板原来 player.play(audioPath) 从头播整块,
导致播的音频跟该行文字对不上(同块多行还都播同一段)。
- SegmentRow 已带 audioStartMs(声纹打通那次顺带加的数据位),这里用上:
  player.play(audioPath, audioStartMs, durationMs) 切片播
- 时间轴 turn 播放顺带简化:不再额外查一次 Segment 取偏移

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lifelog-recorder/app/src/main/kotlin/com/lemon/lifelog/MainActivity.kt
@@ -637,14 +637,8 @@ private fun TimelineTab( @@ -637,14 +637,8 @@ private fun TimelineTab(
637 } else { 637 } else {
638 nowPlayingPeriod = null 638 nowPlayingPeriod = null
639 nowPlayingId = row.id 639 nowPlayingId = row.id
640 - scope.launch {  
641 - val seg = withContext(Dispatchers.IO) { repo.segments.get(row.id) }  
642 - player.play(  
643 - seg?.audioPath ?: row.audioPath,  
644 - seg?.audioStartMs ?: 0L,  
645 - row.durationMs,  
646 - ) { nowPlayingId = null }  
647 - } 640 + // SegmentRow 现在带 audioStartMs,直接切片,无需再查 Segment。
  641 + player.play(row.audioPath, row.audioStartMs, row.durationMs) { nowPlayingId = null }
648 } 642 }
649 }, 643 },
650 ) 644 )
@@ -687,7 +681,8 @@ private fun TimelineTab( @@ -687,7 +681,8 @@ private fun TimelineTab(
687 if (nowPlayingId == row.id) { 681 if (nowPlayingId == row.id) {
688 player.stop(); nowPlayingId = null 682 player.stop(); nowPlayingId = null
689 } else { 683 } else {
690 - nowPlayingId = row.id; player.play(row.audioPath) { nowPlayingId = null } 684 + nowPlayingId = row.id
  685 + player.play(row.audioPath, row.audioStartMs, row.durationMs) { nowPlayingId = null }
691 } 686 }
692 actionRow = null 687 actionRow = null
693 }, 688 },
lifelog-recorder/app/src/main/kotlin/com/lemon/lifelog/PersonProfileScreen.kt
@@ -159,7 +159,12 @@ internal fun PersonProfileScreen( @@ -159,7 +159,12 @@ internal fun PersonProfileScreen(
159 items(fAudio, key = { it.id }) { row -> 159 items(fAudio, key = { it.id }) { row ->
160 AudioRow(row, playing = playingId == row.id) { 160 AudioRow(row, playing = playingId == row.id) {
161 if (playingId == row.id) { player.stop(); playingId = null } 161 if (playingId == row.id) { player.stop(); playingId = null }
162 - else { playingId = row.id; player.play(row.audioPath) { playingId = null } } 162 + else {
  163 + playingId = row.id
  164 + // 块级管线:turn 是块完整录音里的一段,必须按 audioStartMs+durationMs 切片,
  165 + // 否则从头播整块、跟这行的文字对不上。
  166 + player.play(row.audioPath, row.audioStartMs, row.durationMs) { playingId = null }
  167 + }
163 } 168 }
164 } 169 }
165 } 170 }