PrismCore
FFmpeg демуксує, Apple відтворює.
Стек відтворення Apple вміє те, чого не може жоден сторонній плеєр — апаратне декодування, наскрізний Dolby Atmos, Dolby Vision, Match Content. Він просто не відкриє MKV. PrismCore ремуксує будь-який контейнер, який читає libavformat, у HLS-fMP4, роздає його з loopback-сервера й передає звичайному AVPlayer URL плейлиста. Той самий файл, рушій від Apple.
Працює в
Aether
Типовий рушій відтворення на iPhone, iPad, Mac, Apple TV та Apple Vision Pro — увімкнений для кожної інсталяції, не за перемикачем.
Це Swift-пакет, а не фреймворк, який треба збирати. Його візьме будь-що, що вже передає URL в AVPlayer.
Що змінюється, коли ви натискаєте «грати»
PrismCore має бути невидимим: ви відкриваєте фільм, і він грає. А отримуєте ви все те, від чого плеєр, який малює власне зображення, мусить відмовитися.
Ресивер отримує справжній звук
Dolby Atmos виходить із файла бітстрімом і бітстрімом же доходить до ресивера — його ніде не декодують і ніде не сплющують. Ресивер засвічує Atmos тому, що йому справді дали Atmos, а не його стереонаближення.
Телевізор дійсно перемикається в Dolby Vision
На Apple TV панель програмується ще до початку відтворення — частота кадрів, динамічний діапазон, Dolby Vision — тим самим рукостисканням, яке отримують застосунки Apple. Телевізору, який відхилив майстер Dolby Vision, фільм пропонується вдруге без цієї заявки, тож ви бачите зображення, а не помилку.
Це той плеєр, який ви вже знаєте
Меню доріжок, субтитри, Picture in Picture, AirPlay, Match Content, перемотка з пульта — усе це рідний інтерфейс відтворення Apple, бо під ним справді працює плеєр Apple.
Прохолодний пристрій, спокійна батарея
Зображення декодує окремий відеочип, а не процесор, тож MKV коштує стільки ж, як і файл, підтримку якого постачає Apple. Нічого не транскодується — ні на вашому пристрої, ні на сервері, звідки файл прийшов.
Перемотка лишається миттєвою
Мапа всього файла публікується ще до того, як віддано перший кадр, тож стрибок у середину тригодинного фільму просто потрапляє туди й грає, а не готує фільм заново з початку. А тягнучи смугу перемотки, ви бачите кадр, до якого прямуєте, навіть для файла, для якого жоден сервер ніколи не робив мініатюр.
Ніщо не покидає ваш пристрій
Перепакування відбувається на пристрої, а плеєру воно роздається через 127.0.0.1 — loopback-адресу, яка до мережі взагалі не доходить. Жодного кроку в хмарі, жодного акаунта й нічого про те, що ви дивитесь, що можна було б комусь надіслати.
Той трюк, на одній картинці
MKV · MPEG-TS
Контейнер, який Apple не відкриє
Розклад
FFmpeg читає доріжки
HLS-fMP4
Перепаковано на 127.0.0.1
AVPlayer
Власний плеєр Apple
Відео · Аудіо · Субтитри
Файл читається, а не перетворюється
Демуксер FFmpeg відкриває контейнер — MKV, MPEG-TS, AVI — і розділяє його вміст на доріжки: зображення, кожну мову звуку, кожні субтитри. Нічого не декодується й не перетворюється; файл лише розчитується на частини.
Доріжки перепаковуються недоторканими
Те саме стиснене зображення й звук складаються у фрагментовані MP4-частини, які описує плейлист того ґатунку, що AVPlayer відкриває нативно. Змінюється упаковка, а не вміст — біт у біт те саме відео й той самий звук, що були у файлі.
Роздає це локальна адреса
Ці частини AVPlayer отримує з 127.0.0.1 — адреси, яка ніколи не покидає пристрій — так, ніби фільм стрімиться. У цьому весь трюк: плеєр Apple охоче стрімить те, що відмовляється відкрити як файл.
Решту робить рушій Apple
Апаратне декодування, наскрізний Atmos, рукостискання Dolby Vision, меню доріжок, PiP і AirPlay — нічого з цього не переписується, бо з точки зору AVPlayer не діється нічого незвичного.
Двох речей перепакувати не можна, і вони мають окреме поводження. Субтитри, які є зображенням тексту, а не текстом (PGS у блу-рей ремуксах), читає просто на пристрої OCR від Vision, і вони приєднуються як звичайні субтитри. А кілька кодеків, яких Apple не декодує взагалі — VP9, MPEG-2, VC-1 — ідуть другим шляхом, де зображення декодує й малює сам PrismCore; там ви втрачаєте системний інтерфейс плеєра, але фільм грає.
Про що питають
Воно перекодовує мої файли?
Ні. Зображення та звук копіюються точно такими, якими їх прочитали — змінюється лише коробка, у якій вони лежать. І сам файл не змінюється: PrismCore тільки читає його.
То чому AVPlayer не відкриє MKV сам?
Apple постачає підтримку фіксованого списку контейнерів, і MKV до нього не входить — навіть коли відео та звук усередині є форматами, які Apple декодує чудово. Це проблема упаковки, а не декодування, і саме тому перепакування достатньо, щоб її розв’язати.
Що буде зі звуком у TrueHD чи DTS?
Стек Apple не бере їх як бітстрім, тож недоторканими вони пройти не можуть. Замість зводити їх у стерео PrismCore перетворює їх на EAC3 з усіма каналами на місцях — surround лишається surround’ом. Єдине, що цієї дороги не переживає, — Atmos, несений у TrueHD; Atmos в EAC3, який має більшість ремуксів, проходить без змін.
Чи має мій Plex або Jellyfin транскодувати?
Ні, і в цьому значна частина сенсу. Сервер надсилає оригінальний файл, а перепакування відбувається на вашому пристрої — тож немає ні серверного транскодування, яке плавить NAS, ні втраченої на ньому якості.
Це можна вимкнути?
Так — Налаштування ▸ Відтворення в Aether. Типово увімкнено; якщо вимкнути, відтворення повертається до інших рушіїв точно як раніше, для цієї інсталяції й без жодного перевстановлення чи скидання.
Чи довше починається відтворення?
Ні. Джерело відкривається один раз, і з нього читається лише заголовок: це десятки мілісекунд для локального файла й близько десятої частки секунди через мережу — «Готуємо» ви бачите приблизно стільки ж, як для файла, який Apple відкриває напряму.
Усе нижче — про те, як узяти рушій у власний застосунок. Якщо ви тут як глядач, ви вже знаєте всю історію — далі йде сантехніка.
Що воно бере на себе
Контейнери та кодеки
Усе, що читає libavformat — MKV, MPEG-TS, AVI. HEVC, H.264 та AV1 проходять stream copy напряму разом з AAC, AC3, EAC3, FLAC і ALAC. TrueHD, DTS, Opus та решта йдуть через аудіоміст і прибувають як EAC3, а не сплющеними. Анаморфне джерело зберігає форму, яку заявляє його контейнер — у боксі pasp, який AVPlayer шанує.
Dolby Atmos, а не даунмікс
EAC3+JOC копіюється недоторканим і ніколи не декодується в PCM — а бокс dec3, який FFmpeg губить при stream copy, повертається на місце: єдиний сигнал, через який AVFoundation обирає шлях Dolby замість звичайного DD+. Перевірено на ресивері через HDMI.
Dolby Vision та HDR
Profile 5 зберігає свій запис dvh1, Profile 7 через libdovi перетворюється на одношаровий 8.1, а на tvOS панель програмується ще до того, як AVPlayer побачить плейлист — рукостискання має відбутися першим, інакше варіант відхиляється. Майстер, який телевізор не прийняв, повторюється без цієї заявки, а не падає.
Кожна доріжка й кожні субтитри
Кожна аудіодоріжка стає окремою alternate rendition з назвою, мовою та кількістю каналів, тож меню доріжок AVKit просто працює. Текстові субтитри стають сегментованим WebVTT, що переживає PiP і AirPlay; PGS та VOBSUB несуть лише бітмапи, тож їх читає OCR від Vision просто на пристрої, і вони приєднуються як звичайні renditions — доріжка не робить нічого, доки плеєр справді її не запросить, тому ремукс із десятками PGS-доріжок нічого не коштує.
Перемотка як у локальному файлі
Мапа сегментів, вирівняна на ключові кадри, публікується ще до першого пакета, а перемотка поза виробленим вікном на вимогу переприв’язує демуксер до потрібного ключового кадру. Кеш із байтовим бюджетом обмежує диск, а не перемотку — витіснені сегменти просто виробляються знову, а сегмент, який саме роздається, ніколи не стає жертвою витіснення. Виробництво тримається приблизно на хвилину попереду останнього сегмента, який програвач справді завантажив, тож багатогігабайтний файл ніколи не змагається з власним кешем — а читання з джерела осідає біля реального бітрейту фільму, а не швидкості каналу. Контейнер без власного індексу на цьому не застряг: перше послідовне відтворення збирає кожен ключовий кадр, який прочитало, і зберігає мапу, тож наступне планує за нею з першої секунди. Та сама мапа відповідає й SeekPreviewService, який із ключового кадру, що покриває позицію, робить мініатюру для власної смуги перемотки хоста.
Програмний шлях для решти
Кодеки, які AVPlayer не декодує взагалі — VP9, MPEG-2, VC-1 — ідуть через libavcodec у AVSampleBufferDisplayLayer, zero-copy усюди, де VideoToolbox має апаратний декодер. AV1 питає справжній кремній, а не назву чипа, а перевірено черезрядкові джерела лишають нативний шлях заради деінтерлейсера — на GPU, над кадрами, які декодер уже видав, якщо цей фільтр є у складеному FFmpeg.
Швидкий старт відтворення
Раніше відтворення відкривало джерело двічі — один раз для рішення хоста про маршрут, другий для виробництва — а через мережу цей другий відкрив є повним колом усередині очікування, на яке дивиться користувач. Тепер зонд передає сесії свій відкритий контекст, кожне відкриття читає лише те, що потрібно контейнеру, який описує себе сам, а внутрішні очікування перевіряються кожні 10 мс, а не 100. Ремукс 5,4 ГБ HEVC/EAC3 через HTTP доходить від зонда до плейлиста приблизно за 135 мс замість 520 — а файл без індексу перемотки, який інакше сканувався б хвилину, теж запускається, на обмеженому плані.
Ліцензія, яка працює в App Store
LGPL-2.1-or-later з винятком для магазинів застосунків (Application Store Exception). Підписаний застосунок не дає нікому перезлінкувати себе, тож чиста LGPL і роздача через магазин конфліктували; виняток знімає саме цю вимогу для магазинних збірок, а зміни в самому PrismCore лишаються під LGPL і мають бути опубліковані. Публічний API стабільний із 1.0 — зламна зміна означає мажорну версію, і кожен випуск записаний у changelog.
Як це виглядає поруч
На платформах Apple зазвичай доводиться обирати між плеєром, який зберігає все хороше, але відкриває лише контейнери Apple, і тим, що відкриває все, але малює власні кадри й декодує звук у PCM — саме там гинуть Atmos і Dolby Vision. PrismCore узагалі не плеєр: він годує AVPlayer, тож віддавати нічого не треба.
| PrismCore | AVPlayer | VLCKit | libmpv | |
|---|---|---|---|---|
| Відтворює MKV, MPEG-TS, AVI | ||||
| Dolby Atmos проходить як бітстрім | ||||
| Dolby Vision вмикається на дисплеї | ||||
| Match Content на tvOS — частота та діапазон | ||||
| Рідний плеєр Apple: меню доріжок, PiP, AirPlay | ||||
| VP9, MPEG-2 та VC-1 |
VLCKit і libmpv малюють у власний шар і віддають вам PCM, тому середні рядки в них не виходять — це наслідок володіння шляхом рендерингу, а не недогляд. AVPlayer не проходить перший і останній рядок, бо приймає лише контейнери, підтримку яких постачає Apple.
Як почати
Додайте пакет і передайте йому URL. Одна точка входу досліджує джерело й повертає або плейлист для AVPlayer, або програмний конвеєр, уже запущений.
.package(url: "https://github.com/Wenzlik/PrismCore.git", from: "1.8.7")switch try await PrismCoreEngine.open(url: mkvURL) {
case .remux(let session, let playlist):
player.replaceCurrentItem(with: AVPlayerItem(url: playlist))
…
await session.stop()
case .software(let pipeline):
hostView.layer.addSublayer(pipeline.displayLayer!)
pipeline.play()
}Коли перше відтворення вже працює, варто знати про дві опції. Дайте сесії каталог для кешу — і контейнер, який не має власного індексу, збере його просто під час гри, тож наступне відтворення перемотується як індексований файл. Той самий каталог живить і мініатюри для смуги перемотки: це власний невеликий конвеєр — окремий контекст, декодування на CPU, кеш за ключовими кадрами — тож вони ніколи не гальмують відтворення, до якого належать, з будь-яким рушієм на екрані.
let session = try PrismCoreSession(url: mkvURL, keyframeIndexCacheDirectory: caches)
let previews = SeekPreviewService(url: mkvURL, keyframeIndexCacheDirectory: caches)
let frame: CGImage = try await previews.thumbnail(at: 42 * 60)Мінімальні версії — iOS 16, tvOS 17, macOS 14 і visionOS 1. FFmpeg приходить через динамічні xcframework від MPVKit, тож хост, який уже везе MPVKit, не додає жодних нових бінарних залежностей. Якщо залежності за вас розв’язує CI, закріпіть точну версію й тримайте закомічений Package.resolved у злагоді з нею — інакше збірка на пристрої та збірка в TestFlight тихо працюють на різних рушіях.
Просто хочете щось подивитися?
Це була розробницька половина сторінки. Якщо ви тут, щоб дивитися власні фільми й серіали, PrismCore уже робить свою роботу всередині Aether — думати про нього не доведеться.
Подивитися AetherPrismCore створює Václav Zmrhal · zmrhal.cz