fix(tvos): make EAC3 playback conform to Dolby's guidance
Groundwork for #1300. Establishes the session, buffering and route handling Dolby's application guide prescribes, and adds the diagnostic arm needed to find out whether Apple's sample-buffer renderer can carry Atmos objects at all. Audio session, per the guide's sequence: - Adopt the long-form playback profile in one atomic call at app launch and activate the session there. The SDK only accepts that policy with category Playback, a Default/MoviePlayback/SpokenAudio mode and no options, so it cannot be assembled from separate calls. - Report the resolved rendering mode in the player, hidden unless the system resolves it. Apple only resolves it for CarPlay and AirPlay, so an unresolved value means unknown, never "not Dolby". Diagnostics (Apple TV only, Settings > Video Playback > Atmos Output Test): - Add a sample-buffer arm. It reads the asset with AVAssetReader at outputSettings nil and hands the untouched compressed buffers and the untouched format description straight to the renderer, with a variant that rebuilds the description the way playback builds it. Every existing mode went through AVPlayer, so nothing exercised the path playback actually uses; this is what tells us whether the renderer or our construction is at fault. - Add an AirPlay route picker. AirPlay is the only route where the system resolves the rendering mode and the supported channel layouts, so it is what makes those observations reachable at all, and the AVPlayer arms now allow external playback so every arm can be compared on the same destination. - Add a session-mode toggle for the one profile difference between the guide and previous playback behaviour. - Report the session profile, supported layouts, both format descriptions, the magic cookie and the renderer status, and release the session on stop so a failed run cannot contaminate the next one. Also bumps MPVKit to 1.0.14, which carries the matching audio output work: the channel layout AVFoundation itself uses for Dolby content, a renderer-failure observer so the fallback to PCM can actually run, the prescribed feed ordering and preroll, flush recovery that re-supplies the discarded audio instead of shifting later audio into its place, and capability-driven fallback on route and capability changes. This does not yet fix #1300. Whether the sample-buffer renderer can carry JOC is still unknown; it removes every difference from the documented setup that could explain the failure, and gives us the arm to answer it on real hardware.
This commit is contained in:
@@ -418,6 +418,15 @@ class _Translations$settings$bg extends Translations$settings$en {
|
||||
@override String get atmosTestRawStreamDescription => 'Стриймва тестовия файл точно както Atmos възпроизвеждането в плейъра. Изисква URL на тестовия файл.';
|
||||
@override String get atmosTestRawFile => 'Суров EAC3 файл';
|
||||
@override String get atmosTestRawFileDescription => 'Възпроизвежда тестовия файл с известна дължина. Изисква URL на тестовия файл.';
|
||||
@override String get atmosTestAsbarNative => 'Рендер със семпъл буфер (native)';
|
||||
@override String get atmosTestAsbarNativeDescription => 'Подава несменения компресиран звук от файла директно към системния рендер. Изисква URL на тестовия файл.';
|
||||
@override String get atmosTestAsbarGenerated => 'Рендер със семпъл буфер (възстановен)';
|
||||
@override String get atmosTestAsbarGeneratedDescription => 'Същото, но с аудиоописание, изградено както при възпроизвеждане. Изисква URL на тестовия файл.';
|
||||
@override String get atmosTestSessionMode => 'Използвай режим за възпроизвеждане на филми';
|
||||
@override String get atmosTestSessionModeDescription => 'Изключено използва режима, документиран от Dolby. Включено използва предишния режим.';
|
||||
@override String get atmosTestShowRoutePicker => 'Избери AirPlay изход';
|
||||
@override String get atmosTestHideRoutePicker => 'Скрий избора на AirPlay изход';
|
||||
@override String get atmosTestRoutePickerDescription => 'Изпраща теста към AirPlay приемник. Само AirPlay съобщава разрешения аудиорежим.';
|
||||
@override String get atmosTestStop => 'Спри теста';
|
||||
@override String get atmosTestUrl => 'URL на тестовия файл';
|
||||
@override String get atmosTestUrlDescription => 'HTTP URL на суров .ec3 Dolby Atmos файл (напр. извлечен с ffmpeg)';
|
||||
@@ -1514,6 +1523,11 @@ class _Translations$videoSettings$bg extends Translations$videoSettings$en {
|
||||
@override String get audioOutput => 'Аудио изход';
|
||||
@override String get performanceOverlay => 'Оверлей за производителност';
|
||||
@override String get audioPassthrough => 'Директно предаване на аудио';
|
||||
@override String get audioOutputDolbyAtmos => 'Dolby Atmos';
|
||||
@override String get audioOutputDolbyAudio => 'Dolby Audio';
|
||||
@override String get audioOutputSurround => 'Съраунд';
|
||||
@override String get audioOutputSpatial => 'Пространствено аудио';
|
||||
@override String get audioOutputStereo => 'Стерео';
|
||||
@override String get audioNormalization => 'Нормализиране на силата на звука';
|
||||
@override String get audioDownmix => 'Смесване до стерео';
|
||||
}
|
||||
@@ -2463,6 +2477,15 @@ extension on TranslationsBg {
|
||||
'settings.atmosTestRawStreamDescription' => 'Стриймва тестовия файл точно както Atmos възпроизвеждането в плейъра. Изисква URL на тестовия файл.',
|
||||
'settings.atmosTestRawFile' => 'Суров EAC3 файл',
|
||||
'settings.atmosTestRawFileDescription' => 'Възпроизвежда тестовия файл с известна дължина. Изисква URL на тестовия файл.',
|
||||
'settings.atmosTestAsbarNative' => 'Рендер със семпъл буфер (native)',
|
||||
'settings.atmosTestAsbarNativeDescription' => 'Подава несменения компресиран звук от файла директно към системния рендер. Изисква URL на тестовия файл.',
|
||||
'settings.atmosTestAsbarGenerated' => 'Рендер със семпъл буфер (възстановен)',
|
||||
'settings.atmosTestAsbarGeneratedDescription' => 'Същото, но с аудиоописание, изградено както при възпроизвеждане. Изисква URL на тестовия файл.',
|
||||
'settings.atmosTestSessionMode' => 'Използвай режим за възпроизвеждане на филми',
|
||||
'settings.atmosTestSessionModeDescription' => 'Изключено използва режима, документиран от Dolby. Включено използва предишния режим.',
|
||||
'settings.atmosTestShowRoutePicker' => 'Избери AirPlay изход',
|
||||
'settings.atmosTestHideRoutePicker' => 'Скрий избора на AirPlay изход',
|
||||
'settings.atmosTestRoutePickerDescription' => 'Изпраща теста към AirPlay приемник. Само AirPlay съобщава разрешения аудиорежим.',
|
||||
'settings.atmosTestStop' => 'Спри теста',
|
||||
'settings.atmosTestUrl' => 'URL на тестовия файл',
|
||||
'settings.atmosTestUrlDescription' => 'HTTP URL на суров .ec3 Dolby Atmos файл (напр. извлечен с ffmpeg)',
|
||||
@@ -2690,6 +2713,8 @@ extension on TranslationsBg {
|
||||
'videoControls.language' => 'Език',
|
||||
'videoControls.noSubtitlesFound' => 'Не са намерени субтитри',
|
||||
'videoControls.noSubtitlesAvailable' => 'Няма налични субтитри',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'videoControls.noAudioTracksAvailable' => 'Няма налични аудиопътечки',
|
||||
'videoControls.noTracksAvailable' => 'Няма налични пътечки',
|
||||
'videoControls.subtitleDownloaded' => 'Субтитърът е изтеглен',
|
||||
@@ -2699,8 +2724,6 @@ extension on TranslationsBg {
|
||||
'messages.markedAsWatched' => 'Маркирано като гледано',
|
||||
'messages.markedAsUnwatched' => 'Маркирано като негледано',
|
||||
'messages.markedAsWatchedOffline' => 'Маркирано като гледано (ще се синхронизира, когато сте онлайн)',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'messages.markedAsUnwatchedOffline' => 'Маркирано като негледано (ще се синхронизира, когато сте онлайн)',
|
||||
'messages.autoRemovedWatchedDownload' => ({required Object title}) => 'Автоматично премахнато: ${title}',
|
||||
'messages.autoRemovedWatchedDownloads' => ({required num n}) => (_root.$meta.cardinalResolver ?? PluralResolvers.cardinal('bg'))(n, one: 'Автоматично премахнато ${n} гледано изтегляне', other: 'Автоматично премахнати ${n} гледани изтегляния', ),
|
||||
@@ -3204,6 +3227,8 @@ extension on TranslationsBg {
|
||||
'watchTogether.codeMustBe5Chars' => 'Кодът на сесията трябва да е 5 символа',
|
||||
'watchTogether.joinInstructions' => 'Въведете кода на сесията от организатора, за да се присъедините.',
|
||||
'watchTogether.failedToCreate' => 'Неуспешно създаване на сесия',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.failedToJoin' => 'Неуспешно присъединяване към сесия',
|
||||
'watchTogether.sessionCodeCopied' => 'Кодът на сесията е копиран в клипборда',
|
||||
'watchTogether.relayUnreachable' => 'Релейният сървър е недостъпен. Възможно е интернет доставчикът да блокира гледането заедно.',
|
||||
@@ -3213,8 +3238,6 @@ extension on TranslationsBg {
|
||||
'watchTogether.joinCurrentPlaybackDescription' => 'Върнете се към това, което организаторът гледа в момента',
|
||||
'watchTogether.failedToOpenCurrentPlayback' => 'Неуспешно отваряне на текущото възпроизвеждане',
|
||||
'watchTogether.participantJoined' => ({required Object name}) => '${name} се присъедини',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.participantLeft' => ({required Object name}) => '${name} напусна',
|
||||
'watchTogether.participantPaused' => ({required Object name}) => '${name} постави на пауза',
|
||||
'watchTogether.participantResumed' => ({required Object name}) => '${name} продължи',
|
||||
@@ -3413,6 +3436,11 @@ extension on TranslationsBg {
|
||||
'videoSettings.audioOutput' => 'Аудио изход',
|
||||
'videoSettings.performanceOverlay' => 'Оверлей за производителност',
|
||||
'videoSettings.audioPassthrough' => 'Директно предаване на аудио',
|
||||
'videoSettings.audioOutputDolbyAtmos' => 'Dolby Atmos',
|
||||
'videoSettings.audioOutputDolbyAudio' => 'Dolby Audio',
|
||||
'videoSettings.audioOutputSurround' => 'Съраунд',
|
||||
'videoSettings.audioOutputSpatial' => 'Пространствено аудио',
|
||||
'videoSettings.audioOutputStereo' => 'Стерео',
|
||||
'videoSettings.audioNormalization' => 'Нормализиране на силата на звука',
|
||||
'videoSettings.audioDownmix' => 'Смесване до стерео',
|
||||
'performanceOverlay.color' => 'Цвят',
|
||||
|
||||
Reference in New Issue
Block a user