feature: Segment end offset

This commit is contained in:
2026-04-21 17:25:48 +08:00
parent a4dee6d59b
commit e0ab4e4f7e
13 changed files with 53 additions and 28 deletions
@@ -65,6 +65,12 @@ namespace OCES.Audio
Start,
SameAsCurrentSegment,
}
public enum SyncSegment
{
Start,
LastPlayedSegment,
}
public interface IBinarySerializable
{
@@ -289,8 +289,11 @@ namespace OCES.Audio
yield return new WaitUntil(() => done || parentHandle.Cancelled);
if (parentHandle.Cancelled && child != null)
Stop(child);
if (!parentHandle.Cancelled || child == null)
yield break;
Stop(child);
parentHandle.ChildHandles.Remove(child);
}
/// <summary>
@@ -333,20 +336,28 @@ namespace OCES.Audio
var handle = new ContainerPlayHandle();
handle.ActiveSources.Add(source);
handle.Coroutine = this.m_coroutineHost.StartCoroutine(
WaitSegmentFinish(source, handle, onFinished));
WaitSegmentFinish(source, handle, onFinished, segment.EndOffset));
return handle;
}
IEnumerator WaitSegmentFinish(AudioSource source, ContainerPlayHandle handle, Action onFinished)
IEnumerator WaitSegmentFinish(AudioSource source, ContainerPlayHandle handle, Action onFinished, double endOffset)
{
double effectiveTime = endOffset > 0f ? source.clip.length - endOffset : 0f;
// 1. 等待"逻辑结束"EndOffset 或自然结束)
yield return new WaitWhile(() =>
source.isPlaying &&
!handle.Cancelled &&
source.time < effectiveTime);
// 2. 立即通知 container 推进
if (!handle.Cancelled) onFinished?.Invoke();
// 3. 如果 source 还在物理播放(EndOffset 提前退出的情况),等它自然结束并清理资源
yield return new WaitWhile(() => source.isPlaying && !handle.Cancelled);
source.Stop();
ReturnSource(source);
handle.ActiveSources.Remove(source);
if (!handle.Cancelled)
onFinished?.Invoke();
}
// ─────────────────────────────────────────────