黑色镜子:班德斯纳奇—этоинтерактивноешоу«выберисвоеприключение»,котороеследуетзаошеломоеодрам Netflix的недавновыпустилаэтотновыйэпизодизсерийтехнологическойантиутопии«Черноезеркало»,потративзначительноеколичествовременииэнергиинасозданиеновойтехнологии«отслеживаниясостояния(状态跟踪)»,чтобывключитьинтерактивностьвэтотраз。
注意:通过Netflix的镜玻璃Автор:乔恩· 恩格斯曼( Jon Engelsman)
Вэтойстатьемырассмотримбазовыеструктурыданныхикод,которыйNetflix的разработалдляэтогослучая,исследуясетевыевызовыибольшиеструктурыданныхJSON,чтобыпопытатьсяразобратьсявихбезумии。
Выберисвоеприключение
Bandersnatch —этошоуВВыберисвоеприключение»оком-то,ктопытаетсясоздатьвидеоигруВеберсе Нохитростьсисториями«выберисебеприключение»заключаетсявтом,чтоонинеследуютлинейнымсюжетнымлиниям,подобнымтрадиционнымповествованиям,вместоэтогопредлагаянесколькосюжетныхлинийсразнымиокончаниями,всевзависимостиотвыбора,которыйвыделаетенасвоемпути。 Втовремякакнелинейноеповествованиенапротяжениидесятилетийбылонеотъемлемойчастьюиндустриивидеоигр,егореализациянакрупнойплатформепотоковогомедиазаслуживаетвнимания。
Netflix发行人Bandersnatch,Netflix,зрителюпредоставляетсявыбор,которыйпоявляетсянаэкране。 Выбородноговариантаиздругогоизменяетвидео,котороевывидите,когдаразвораииеесовновый。

Несколькотрудолюбивыхзрителейна书签交易попыталисьнаметитьварианты,разветвленныесюжетныелиниииокончаниядляистории 想象猛兽 ,примеркоторойпоказанниженаблок-схеме,разработаннойпользователем书签交易AppiusClaudius。

Общийэффектотпредоставлениявыбораиобеспечениебесперебойноговидеовпечатляето.Таккаксе
Netflix的Интерактивныеразвлеченияна
班德斯纳奇(Bandersnatch) — Netflix Netflix的照片,простоонпервый,нацеленныйнавзрослуюаудито。 Впрошломгодуонивпервыепредставилисвоюпервуюпопыткуиспользованияинтерактивныхмедиавдетскомсериале«Котвсапогах:вловушкеэпическойсказки»。 ИсогласностраницесправкиNetflix,影集5наименованийинтерактивноеотот。
Но,вероятно,справедливобудетсказать,чтоBandersnatchявляетсясамымамбициозныминтенаненнемназва Настолько,чтоимпришлосьсоздатьновуютехнологию«отслеживаниясостояния»,чтобысправитьсяс«миллионамиизмененийвтом,каквыможетепроигратьэтуисторию»,считаетКарлаЭнгельбрехт,директорNetflix的поинновациямпродуктов。
Такчтожеэтозатехнологияотслеживаниясостоянияикаконаработает? Чтобыпонятьэто,ясделалто,чтовсегдаделаю,когдамнеинтересно,каквеб-сайтыделаютуд。 наначалкопатьсявисходномкодеисетевыхзвонках!
СетевыеЗвонки
Chrome开发人员工具ВовремяпросмотраBandersnatch,在веретевывыевыевызовы。 Вчастности,яискалчто-нибудь,чтомоглобыиметьотношениекинтерактивностиилиотслеоииванис。 Мониторингсетевыхзвонковвовремяпросмотраивыборавовремяшоу,похоже,чтоесть5разныхURL-а

nflxvideo.net
БольшимтрудомприпредоставлениеконтентаявляютсяGET-запросыкконечнойточкеnflxvideo.netвои Онибыстроимногократновозвращаютмедиаданные,чтобызрительникогданеиспытывалбуферизаци。
`https://ipv4-c330-nyc001-ix.1.oca.nflxvideo.net/range/2727743-2752470?o=AQFn7d5Kh9LAp4jb6mieUi1lPH5kaAzEkOl_fiWm5Nwl9KZnnKTMLCgs0wPM4K8SZt3gZHeUzupAIiSM6UEicfursSFWTuhGvv8-ifgf_JxsrhoKVLOv_uF9PyDUsVDtbX7w9tYwR0WXIGRpo4Z3y4clZfW8J3Cu0zFlO2IzhkLUD5ovVgh7r5XMYvCZ9rkucx06MFp0SHOvTy3uk-QcjQ&v=3&e=1546178203&t=qyg5yHh9iczoSr_tvN3prltdmRc&sc=Eq%1F3%25Uc%03k%0Et%7DV%5DRh%0Cf%05Bh7%1F%5Ey%7C%05CY%5B`
ПобольшейчастиэтивызовывыглядятдовольностандартнодлябольшинствапотоковконтентаNetflix公司,поэтомуони,вероятно,непоказываютничегоуникального,чтомоглобыпомочьнампонятьинтерактивность。
Персонализация
Другойнаборсетевыхвызововвыглядитболеемногообещающим,вызовыперсонализации。 personтизапросыPOSTотправляютдвоичныеданныевконечнуюточку /personalization/cl2
cl2восновномдоменеwww.netflix.com。
`https://www.netflix.com/personalization/cl2`
Двоичныеданные—会话,ID,是JSON,котораявключаетвсебямногоожидаемойинфии。 Ноонтакжевключаетвсебяобъект«состояния»,которыйможетрассказатьнамчто-тониеоин。
MSL和Cd
Существуетдвасетевыхвызова,которыеотправляютPOST-запросы或API-интерфейсуровнябезопасностисообщ。
События:
`https://www.netflix.com/nq/msl_v1/cadmium/pbo_events/%5E1.0.0/router`
lobурналBlob:
`https://www.netflix.com/nq/msl_v1/cadmium/pbo_logblobs/%5E1.0.0/router`
MSтотMSL APIиспользуетсядля«передачиданныхмеждудвумяилиболеевзаимодействующимиобъектами»。 Похоже,чтоэтисетевыевызовыотправляютданныежурнала/событий,связанныесCadmium,доноеном。
Похоже,чтоданныеэтихвызововсодержатданныеотокенеиподписипользователя,нонеяттона Однако,посколькуподобныевызовырегулярноотправляютсявовремяпотоковойпередачинеинтерактивногомультимедиа,вполневероятно,чтоэтивызовынезадействованывкакой-либоинтерактивнойфункции。
Ядолженотметить,чтояопустилмногодеталейвэтихсетевыхзапросах,особенизаг д。 Япростовытащилдостаточнодеталей,чтобыпопытатьсяпонятьсутьпроисходящего,нояпризывю
沙克提
Ипоследнее,нонеменеевнашемспискесетевыхвызовов—从POST API API Netflix Shake到Shake。
`https://www.netflix.com/api/shakti/vdf992f93/pathEvaluator?drmSystem=widevine&isWatchlistEnabled=false&isShortformEnabled=false&isVolatileBillboardsEnabled=false&method=call&falcor_server=0.1.0&withSize=true&materialize=true`
,тотсетевойзапроснасинтересует,поэтомудавайтерассмотримегоболееподробно。
沙克提
Shakti API,Изнебольшойобщедоступнойинформациикажется— —对службаизвлеченияданных的看法。 Имя«沙克蒂»краткоупоминаетсянаслайде2014годаотРайанаАнклама,тогдашнегостаршегоинженерапользовательскогоинтерфейсавNetflix公司,гдеобсуждалисьновыеуслугиNode.js的вкомпании。

Онтакжеупоминаетсяврепозиторииgithub上стемжеименемотпользователяHowardStark,однако,похоже,этоскореепопыткареверс-инжинирингаизвне,чемлюбоеофициальноеописаниесервисаNetflix的。
Итак,您是否在API Shakti,ночтоещездесьпродставлениеотом,какимможет? API API Shakti,кажется,чтовURLзапросеестьпараметрзапросасименемfalcor_server。Shaтож, falcor_server
ПосколькуFalcor – этопользовательскаябиблиотека的JavaScript的Netflixдля«эффективногоизвлеченияданных»,идеяотом,что沙克蒂 – этоAPIизвлеченияданных,похоже,подтверждается。
Shakti的CallPaths
API Shakti是Ещеоднуважнуювещь,которуюстоитотметитьсотношениисетевыхвы。 Несмотрянато,чтоихURLвыглядятодинаково,по-видимому,существуеткакминимум8различныхтиповвы Болееконкретно,значениямидляключасименемcallPathвбинарнойзагрузкеданныхJSON。 ОсновываясьнакраткомчтениидокументацииFalcor,этаполезнаязагрузка,вероятно,используетсяFalcor,гдезначениядляCALLPATHнаправляютсякразличнымвнутреннимслужбам。
5个Shakti callPaths ,可在其中找到。
- 里诺/洛洛莫:
"callPath":["reno","newLolomo"]
- 播放前:
"paths":[["videos",80988062,"bookmarkPosition"],["videos",80988062,"preplay",-1,"experience"],["videos",80988062,"preplay",-1,"playbackVideos",{"from":0,"to":1},["availability","bookmarkPosition","creditsOffset","current","requiresPreReleasePin","runtime","summary"]]]
- 发布后播放:
"callPath":["videos",80988062,"postplay"]
- 咨询:
"callPath":["videos",80988062,"advisories"]
- 动态消息:
"callPath":["dynamicMessages"]
Ноподождите,чтоэто! Покрайнеймере3из8 callPath ’s ,используемыхвзапросахShakti,содержатслово «интерактивный» 。
- logInteractivePlaybackImpression:
"callPath":["logInteractivePlaybackImpression"]
- logInteractiveStateSnapshots:
"callPath":["logInteractiveStateSnapshots"]
- InteractiveVideoMoments:
"callPath":["videos",80988062,"interactiveVideoMoments"]
.товыглядитмногообещающе。 Мывидимнетолькослово«интерактивный»,ноислово«состояние»。 Мыещепозжевернемсяклвем«логам» callPath ,носейчасдавайтепроверимответInteractiveVideoMoments callPath 。
InteractiveVideoMoments
InteractiveVideoMoments callPath — 1月6日1月6日API Shakti,которыевызываютсяпризагрузкестраницы,икажется,чтонтвызы Поэтомуразумнопредположить,чтоэтосвоегородавызовинициализации。
调用callInteractiveVideoMoments和чтоонибольши的Нонаиболеезаметнойвещью。 Действительнобольшие。 JSONдлинойболее25 000строк。
Прикопированииданныхответовнижеявырезалбольшуючастьреальногосодержимого,чтобыпоказать的图片。
{
“ jsonGraph”:{
“视频”:{
“ 80988062”:{
“ interactiveVideoMoments”:{
“ $ type”:“ atom”,
“ $ size”:273073,
“值”:{
“ type”:“ bandersnatch”,
“ choicePointNavigatorMetadata”:{
“配置”:{
},
“故事情节”:{
},
“ type”:“快照”,
“ choicePointsMetadata”:{
“ timelineLabel”:[],
“ choicePoints”:{...},
“选择”:null
}
},
“ commonMetadata”:{
“版式”:{...},
“设置”:{...}
},
“ segmentHistory”:[],
“ stateHistory”:{...},
“快照”:[],
“ momentsBySegment”:{...},
“前提条件”:{...},
“ audioLocale”:“ en”,
“ segmentGroups”:{...}
}
}
}
}
},
“路径”:[
[
“视频”,
“ 80988062”,
“ interactiveVideoMoments”
]
]
}
ВэтомJSON Graph,по-видимому,естькакминимум4компонента,которыеопределяютинтерактивныекомпонers
- stateHistory: инициализация62переменныхсостояний(59булевыхи3многомерных)
- momentBySegment:списоксегментоввидеопотипу(сцены,показы,пост-воспроизведениеитд。),описывающийпредварительныеусловиясостояния,новыеданныеосостоянииивариантывыбора(такжеопределенныесегментами)。
- 前提条件:списокопределенийпредварительныхусловийдлякаждогосегмента,определяемыхпростойилисложнойусловнойлогикойсиспользованием переменныхсостояния
- segmentGroups: списоктого,какидентификаторыгруппысегментовисегменты,которыеихсоставлеюлетвключаяп
Давайтерассмотримнекоторыекомпонентыболееподробносточки зренияпервоговыборав 想象猛兽 ,гдепапаСтефанаспрашивает,хочетлион糖泡芙илиFrostiesхлопья。

Историясостояния
Давайтенаонсоспискаисториисостояния 。 Напервыйвзгляд,этотсписокпараметровсостоянияговоритнамнемного。 Номызнаем,чтоэтокакая-тоинициализациясостояния,и,посколькумызнаем,чтоNetflix的создалновуютехнологию«отслеживаниясостояний»дляэтойинтерактивнойфункции,япредполагаю,чтоэтоважныйкомпонент! Мывернемсякэтому。
“ stateHistory”:{
“ p_sp”:是的,
“ p_tt”:是的,
“ p_8a”:否,
“ p_td”:是的,
“ p_cs”:否,
“ p_w1”:否,
“ p_2b”:否,
“ p_3j”:否,
“ p_pt”:否,
“ p_cd”:否,
“ p_cj”:否,
“ p_sj”:否,
“ p_sj2”:否,
“ p_tud”:否,
“ p_lsd”:否,
“ p_vh”:否,
“ p_3l”:否,
“ p_3s”:否,
“ p_3z”:否,
“ p_ps”:“ n”,
“ p_wb”:否,
“ p_kd”:否,
“ p_bo”:否,
“ p_5v”:否,
“ p_pc”:“ n”,
“ p_sc”:否,
“ p_ty”:否,
“ p_cm”:否,
“ p_pr”:否,
“ p_3ad”:否,
“ p_s3af”:否,
“ p_nf”:否,
“ p_np”:否,
“ p_ne”:否,
“ p_pp”:否,
“ p_tp”:否,
“ p_bup”:否,
“ p_be”:否,
“ p_pe”:否,
“ p_pae”:否,
“ p_te”:否,
“ p_snt”:否,
“ p_8j”:否,
“ p_8d”:否,
“ p_8m”:否,
“ p_8q”:否,
“ p_8s”:否,
“ p_8v”:否,
“ p_vs”:“ n”,
“ p_scs”:否,
“ p_3ab”:否,
“ p_3ac”:否,
“ p_3aj”:否,
“ p_3ah”:否,
“ p_3ak”:否,
“ p_3al”:否,
“ p_3af”:否,
“ p_5h”:否,
“ p_5ac”:否,
“ p_5ag”:否,
“ p_5ad”:否,
“ p_6c”:否
}
Моментыпосегментам
Затем,просматриваясписокmomentBySegment,мысталкиваемсяссегментом1A,который,кажется,связансэтимпервымвыборомвшоу,между糖泡芙(выбор1E)иFrosties(выбор1D)。
“ 1A”:[
{
“ type”:“ scene:cs_bs”,
“ startMs”:135880,
“ endMs”:153520,
“ activationWindow”:[
135880,
149520
],
“ id”:“ 1A”,
“ layoutType”:“ l2”,
“ uiDisplayMS”:139520,
“ uiHideMS”:149520,
“ defaultChoiceIndex”:0,
“ choiceActivationThresholdMS”:135880,
“选择”:[
{
“ id”:“ 1E”,
“ segmentId”:“ 1E”,
“ startTimeMs”:153520,
“ text”:“糖浆”
},
{
“ id”:“ 1D”,
“ segmentId”:“ 1D”,
“ startTimeMs”:5442480,
“ text”:“ FROSTIES”
}
],
“ trackingInfo”:{
“ viewableId”:80988062
},
“ impressionData”:{
“ type”:“ userState”,
“数据”:{
“持续”:{
“ p_sp”:是的,
“ p_tt”:是的,
“ p_8a”:否,
“ p_td”:是的,
“ p_cs”:否,
“ p_w1”:否,
“ p_2b”:否,
“ p_3j”:否,
“ p_pt”:否,
“ p_cd”:否,
“ p_cj”:否,
“ p_sj”:否,
“ p_sj2”:否,
“ p_tud”:否,
“ p_lsd”:否,
“ p_vh”:否,
“ p_3l”:否,
“ p_3s”:否,
“ p_3z”:否,
“ p_ps”:“ n”,
“ p_wb”:否,
“ p_kd”:否,
“ p_bo”:否,
“ p_5v”:否,
“ p_pc”:“ n”,
“ p_sc”:否,
“ p_ty”:否,
“ p_cm”:否,
“ p_pr”:否,
“ p_3ad”:否,
“ p_s3af”:否,
“ p_nf”:否,
“ p_np”:否,
“ p_ne”:否,
“ p_pp”:否,
“ p_tp”:否,
“ p_bup”:否,
“ p_be”:否,
“ p_pe”:否,
“ p_pae”:否,
“ p_te”:否,
“ p_snt”:否,
“ p_8j”:否,
“ p_8d”:否,
“ p_8m”:否,
“ p_8q”:否,
“ p_8s”:否,
“ p_8v”:否,
“ p_vs”:“ n”,
“ p_scs”:否,
“ p_3ab”:否,
“ p_3ac”:否,
“ p_3aj”:否,
“ p_3ah”:否,
“ p_3ak”:否,
“ p_3al”:否,
“ p_3af”:否,
“ p_5h”:否,
“ p_5ac”:否,
“ p_5ag”:否,
“ p_5ad”:否,
“ p_6c”:否
}
}
},
“ uiInteractionStartMS”:139520,
“ config”:{
“ intervalBasedVideoTimer”:是的,
“ disableImmediateSceneTransition”:是的,
“ disablePrematureUserInteraction”:是,
“ hideChoiceLabelWhenChoiceHasImage”:是,
“ randomInitialDefault”:true
}
}
]
Здесьестьчтораспаковать,ноестьтривещи,которыевыделяются。 Например,естьнесколькоопределенийвремениначалаиокончаниявмиллисекундах。 Этизначения,кажется,определяютопределенныеразделывидео,которыеотносятсякакксегменту,предшествующемувыбору,такикразличнымсделаннымвыборам。 Такжеследуетотметить,чтосегмент1Аимееттолькоодиннаборопределенийтипа«场景:cs_bs»。
Мытакжеможемвидеть,用户状态массивimpressionDataвыглядиткаксписокпараметровstateHistory 。 Посколькуэтиданные,кажется,независятоттого,какойвыборвыбран,япредполагаю,чтоэтиданныесостоянияобновляютсяещедотого,каквыборбудетсделан,возможно,вкакой-томомент,когдавоспроизводитсяпредыдущийсегментвидео。
Давайтепосмотримнадеталиодногоиздвухвариантов,сегмент1E(糖粉扑):
“ 1E”:[
{
“ type”:“ notification:playbackImpression”,
“ startMs”:153520,
“ endMs”:207240,
“前提条件”:[
“不”,
[
“ eql”,
[
“ persistentState”,
“ p_sp”
],
真正
]
],
“ impressionData”:{
“ type”:“ userState”,
“数据”:{
“持续”:{
“ p_sp”:是
}
}
}
},
{
“ type”:“ scene:cs_bs”,
“ startMs”:190640,
“ endMs”:207240,
“ activationWindow”:[
190640,
203240
],
“ id”:“ 1E”,
“ layoutType”:“ l2”,
“ uiDisplayMS”:194280,
“ uiHideMS”:203240,
“ defaultChoiceIndex”:0,
“ choiceActivationThresholdMS”:190640,
“选择”:[
{
“ id”:“ 1H”,
“ segmentId”:“ 1H”,
“ startTimeMs”:207240,
“ text”:“ THOMPSON TWINS”
},
{
“ id”:“ 1G”,
“ segmentId”:“ 1G”,
“ startTimeMs”:5496880,
“ text”:“ NOW 2”
}
],
“ trackingInfo”:{
“ viewableId”:80988062
},
“ uiInteractionStartMS”:194280,
“配置”:{
“ intervalBasedVideoTimer”:是的,
“ disableImmediateSceneTransition”:是的,
“ disablePrematureUserInteraction”:是,
“ hideChoiceLabelWhenChoiceHasImage”:是,
“ randomInitialDefault”:true
}
}
]
Изсегмента1Aмызнаем,чтосегмент1Eявляетсявыборомдля糖扑。 Вотличиеотсегмента1A,мывидимдванабораопределений:одиндлятипа«场景:cs_bs»деинеониннее Определениедлявтороготипавключаетвсебяпредварительноеусловиедлясостояняяоенее Ярискнупредположить,ч«sp»вp_spозначает«糖扑»。
Определениядля«场景:cs_bs»включаютвсебявремяначалаиконца,атакжеданныеоследующемвыборевконце этогосегмента ,вчастности,выбормузыкальныхлентмежду汤普森双胞胎(сегмент1H)и现在2(сегмент1G)。
Интересноотметить,чтоданныедлясегмента1D(Frosties)оченьпохожинасегмент1E,включаяданныедляпоследующеговыборамеждусегментами1Hи1G,сзаметнымотличиемвтом,чтодляпараметрасостоянияp_spустановленозначение假(тоестьне糖泡芙)。
Мыначинаемвидетьнекоторуютенденцию,поэтомудавайтеподведемитогитого,чтомынашлидосихд。 Изтого,чтомывидели,определениясегментовмогутвключать:
- Времяначалаиконца,относящиесякнекоторойвидеопоследовательности
- Предварительныеусловияпараметровсостояния,связанныхспоказамивоспроизведения(какимибыонин)
- Обновленияпараметровсостояния
- Вариантывыбора(1или2),которыемогутвыполнятьсявнекоторойточкесегмента,
- s:enes:«notification:action»,«not»:«通知:动作»,«播放»
Чтокасаетсяэтихтиповопределениясегмента,то,по-видимому,существуетдватипауведомленийи。 Покаянебудувдаватьсявподробноститого,какэтиопределениясегментовмогутотличаться。
Предварительныеусловия
Нашследующийтипкомпонентаявляетсяпредварительнымусловием 。 班达斯纳奇(Давайтенемногозабежимвперед),从чтобыисследоватьэтотновыйкомпонент。 Вкакой-томоментэпизодаСтефанпосещаетофисдоктораХейнса,изрительсталкиваетсясвыборо
ПросматриваясписокmomentsBySegmentдляэтоговыбора,мыобнаруживаем,чтоонопределенкаксегмент3R。 Затем,ищаэтотидентификаторсегментавспискепредварительныхусловий,мынаходимегоопределен。
“ 3R”:[
“不”,
[
“ persistentState”,
“ p_vh”
]
]
Кажетсядостаточнопростым。 pтотсегментимеетпредварительноеусловиетолькодляоднойпеременнойсостояния, состоянияp_vh (vh =访问海恩斯?) 。 Темнеменее,неясно,чтоименноделаетэтопредварительноеусловие。 Этосвязаносвоспроизведением? Илиэтасцена?
Глядянадлинныйсписокпредварительныхусловий,кажется,чтоонимогутварьироватьсяотпростыхлогическихвыражений,включающихтолькоодносостояние,доболеесложныхвыражений,включающихмногосостояний。 Хотямынезнаемточно,какиспользуютсяэтипредварительныеусловия,былобысправедливопредположить,чтоониявляютсястатическимиопределениями,которыедействуюткаксвоегородауправлениепотокомдля структурыветвящегосясегмента ,открываяизакрываяпутиповествованиявзависимостиот различныхзначенийсостояния 。
Сегментныегруппы
Двайтенасекундуостановимсянасегменте3Rипосмотримнашшпосленнейвете Этикомпоненты,по-видимому,являютсяспособоморганизацииструктурысоединениясегментов。 Некоторыегруппысегментовимеютстатическийнаборсегментов,состоящихвгруппе,втовремякакдругиеимеютдинамическиеопределения,основанныенапредварительныхусловиях。
Например,сегмент3Rотображаетсявдвухразныхгруппахсегментов: VisitHaynesChoiceи3Q 。 ГруппаVisitHaynesChoiceпредставляетсобойколлекциюиз6различныхидентификаторовсегментов。
“ VisitHaynesChoice”:[
“ ZP”,
“ ZQ”,
“ 3Xa”,
“ 3Xac”,
“ 3S”,
“ 3R”
]
Исегментгруппа3Qпредставляетсобойнабориз2идентификаторовсегментов,гдеодинизних(3S),по-видимому,включаетсявгруппутольконаосновекритерияпредварительного условия ,помеченногокак3S_s3Q。
“ 3Q”:[
{
“段”:“ 3S”,
“前提条件”:“ 3S_s3Q”
},
“ 3R”
]
Рассматриваядругиегруппысегментов,мывидимстатическиопределенныегруппы,такиекакVisitHaynesChoice,другиединамическиопределенныеспредварительнымиусловиями,такимикак3Q,идаженекоторые,которыевключаютдругиегруппывсегментегруппы。
Еслиэтоневседостаточнозапутанно,следуетуказать,чтоименаидентификаторовмогутсуществоватьввидеопределенных сегментов ,segmentGroups, 前提条件 илиmomentsBySegmentsимогутсуществоватьтолькокакодинизэтих элементовилииспользоватьодинитотжеидентификатордлянесколькихэлементов.Такимобразом ,какID 3S_s3Qявляетсяпростопредварительнымусловием ,标识ID 3Qявляетсяисегментом, исегментомгруппы 。
Составляемкартувсегоэтого
Отображениеполногопотокавсехэтихразличныхсегментов,групп,предварительныхусловийисоон Чтобыпопытатьсяпонятьэтовсе,нужнопоказать,каклогикаиструктурыданных,неже
Ксчастью,впостена书签交易отпользователяiamthecage,оннетолькопоказываетнам,чтоэпизоднасамомделепредставляетсобойодиночное«мастер»видеопродолжительностьюболее5часов,нотакженашелспособпрограммнопереходитькразличнымчастямвидео。 Этапубликациясодержитнекоторыйкодна的JavaScript,которыйможноввестивконсольразработчика,чтопозволяетвручнуюпереходитькопределенномувремениввидео(вмиллисекундах)。 ,скопировалэтотфрагменткоданижедляудобства,есливызахотитеопробоватьегосамостоятельно。
document.evaluate('// * [@ id =“ 80988062”] / video',document).iterateNext()。setAttribute(“ controls”,“ controls”)
netflix.appContext.getPlayerApp()。getAPI()。getOpenPlaybackSessions()[0] .currentTime
const videoPlayer = netflix
.appContext
。州
.playerApp
.getAPI()
。视频播放器
//获取玩家ID
const playerSessionId = videoPlayer
.getAllPlayerSessionIds()[0]
常量播放器= videoPlayer
.getVideoPlayerBySessionId(playerSessionId)
player.seek(1577120)
Используянашпримерсегмента3Rсверху,мыможемотобразитьнекоторыеизсвязанныхсним видеоклипов ,используявремяначалаиокончания,подробноописанныевкомпонентахchoicePointsиmomentBySegment(показанонарисункениже)。

Этопоказывает,какэтикомпонентыданных(вформатеJSON)определеныикаконисвязанысконкретнымиточками вглавномвидеодляэтогоконкретногосегмента 3R。 Рассматриваяэтопо-другому,мыможемпоказать,какпараметрысостоянияипредварительныеусловиязапускаютразличныекомбинациитиповсегментоввидео(сцены,количествопромоткиит。д。)исвязанныеснимивариантывыбора。

Исходяизэтого,мыможемначатьсмотреть,какэтикомпонентыработаютвместеприсоставленисхем。 Икаконииспользуютсядляпереходакразличнымсегментамосновноговидеовзависимостиоттого,какойвыборсделан,иобщегосостоянияинтерактивнойистории,чтокаким-тообразомприводиткбесперебойнойработемультимедиа。
Хорошо,этокажетсясложным,верно?
Оглядываясьназаднанекоторыеблок-схемы,которыеявиделна书签交易,ядолжензадатьсявопросом,непропускаютлионинекоторыеповествовательныепути,особеннопотому,чтоони,кажется,имеютэлементарнуюзаписьвсехиз62параметровсостояния。 Количествоэлементоввкаждомизрассмотренныхнамиосновныхкомпонентовпоказывает,насколекосложе
- 先决条件 :241(предпосылками)
- momentsBySegment :208(моментыпосегментам)
- segmentGroups :111(сегментгруппы)
- stateHistory :62(историясостояния)
Стакимбольшимколичествомсегментовипараметровсостояниясуществуетбольшаявариативностьвзависимостиотсложностипредварительныхусловийдляразличныхсегментоввидео。
Чтобысправитьсясэтойсложностью,мызнаем,чтоNetflixдолженбылсоздатьновуюпрограммоподназван Воткаксценарист/исполнительныйпродюсерЧарлиБрукерописываетсложностьсоставлениясхемыBandersnatch
Вынемоглисделатьэтовблок-схеме,потомучтоонадинамичнаиотслеживает,вкакомсостояниивынаходитесь,иделаетвсевсоответствиесэтим, – «объяснилБрукер,который»смогввестиивнедритьсвойразвивающийсясценарийнепосредственновNetflix公司»с помощью этого изящного инструмента.
Еще один интересный аспект всего этого заключается в том, что Netflix каким-то образом удалось реализовать эти интерактивные компоненты в контексте их существующей потоковой инфраструктуры. Они сняли видео продолжительностью более 5 часов, построили сложный слой состояния / предусловия / сегментации поверх, а затем разработали процесс перехода назад и вперед к различным точкам основного видео, и все это без какой-либо буферизации видео. Тот факт, что они смогли сделать все это, опираясь на те же сервисы API Shakti, которые они используют для другого контента Netflix, на самом деле говорит о надежности и универсальности сервисов, которые они создают.
Исходный код и Akira
Итак, мы увидели, как Netflix использовал API Shakti для доставки данных инициализации, которые определяют весь интерактивный рассказ и его структуру видео. Но как все это работает вместе, чтобы фактически манипулировать просматриваемым видео и обеспечивать бесперебойную работу с медиа? Создали ли они что-то новое для обработки интерактивного аспекта сегментации видео? Чтобы разобраться в этом, нам нужно проверить исходный код на стороне клиента.
Просматривая теги скрипта на главной HTML-странице заголовка Bandersnatch , я наткнулся на интересную библиотеку JavaScript под названием Akira. Не минифицированный, это более 89 000 строк кода, так что это не маленькая библиотека. URL адрес ниже загружает эту клиентскую библиотеку:
https://codex.nflxext.com/%5E2.0.0/truthBundle/webui/0.0.1-akira-js-mk-v6faf08f4/js/js/akira%7CakiraClient.js/2/4u4A494b4k06424f4z040n004B4e474i4h4c4p4s4n444g4y114v/l/true/none
Я не смог найти какой-либо ссылки на эту конкретную библиотеку Netflix в Интернете, поэтому я не уверен, что это что-то новое или что-то, что Netflix использует это сейчас. Но, глядя на другой эпизод Black Mirror (не интерактивный эпизод), мы видим, что подобная библиотека Akira загружается через URL-адрес запроса ниже:
https://codex.nflxext.com/%5E2.0.0/truthBundle/webui/0.0.1-akira-js-mk-v6faf08f4/js/js/akira%7CakiraClient.js/2/4u4l4A494b4k06424f4z040n004B4e474h4c4p4s4n444g114v/l/true/none
Хотя URL выглядят одинаково, мы видим длинную символьную строку (может быть, хэш?), Которая выглядит немного по-разному в каждом из двух запросов.
Interactive: 4u4A494b4k06424f4z040n004B4e474i4h4c4p4s4n444g4y114v
Non-Interactive: 4u4l4A494b4k06424f4z040n004B4e474h4c4p4s4n444g114v
Не минифицированная не интерактивная библиотека Akira показывает чуть менее 83 000 строк кода, примерно на 6 000 строк меньше, чем интерактивная версия. И беглое сравнение этих библиотек показывает, что интерактивная библиотека Akira имеет ссылки на четыре интерактивных компонента, которые мы исследовали ( preconditions , stateHistory , momentBySegment и segmentGroups ), а не интерактивная библиотека Akira — не имеет ссылок.
Таким образом, похоже, что эта библиотека Akira обрабатывает большинство (или все) клиентские функции технологии «отслеживания состояний» Netflix, теоретически обновляя значения состояний, оценивая предварительные условия и перемещаясь между сегментами видео, все на основе компонентов данных, загруженных API Shakti.
Хотя неясно, создал ли Netflix библиотеку Akira специально для Bandersnatch , этот эпизод содержит тонкий (если не анахроничный) намек на одноименную мангу Katsuhiro Otomo 1982 года с таким же названием. Во время визита Стефана в квартиру Колина на заднем плане вырисовывается крупный черно-белый отпечаток, показывающий разрушение Нео-Токио. Я хотел бы думать, что это ссылка на библиотеку JavaScript, которая, кажется, сделала возможным использование Bandersnatch .

ОБНОВЛЕНИЕ : Оказывается, Netflix уже давно использует клиент Akira! Я нашел статью 2015 года о взаимодействии Netflix, где бывший директор по инженерным работам Джош Эванс дал следующий комментарий:
«Мы создали то, что мы называем нашим пользовательским интерфейсом «Дарвин», перемещая формы от вертикальных к горизонтальным кадрам, и мы настроили наши алгоритмы… появилось много инноваций, — говорит Эванс.
Интерфейс такого же типа есть и на сайте, создавая то, что Эванс называет пользовательским интерфейсом «Акира».
«Вся необходимая информация у вас под рукой», — говорит он. Это звучит просто, но оно основано на передовой телеметрии, аналитике в реальном времени и продвинутом машинном обучении.
Поэтому, хотя кажется, что Netflix уже давно использует пользовательский интерфейс Akira, я все же считаю важным отметить, что они обслуживают две разные версии клиентской библиотеки, в зависимости от того, является ли она интерактивной или нет.
Сквозь зеркало
Понятно, что Netflix приложила немало усилий для разработки этой интерактивной технологии для Bandersnatch . Чтобы сделать это, они разработали JSON Graph, специально для повествования, более 6000 строк нового клиентского кода и даже новый инструмент Branch Manager, чтобы выстроить сложную повествовательную структуру эпизода.
Эта статья является попыткой понять часть этой работы, изучить и обдумать детали, которые вошли в новую потоковую технологию, стоящую за Bandersnatch . Интересно будет посмотреть, какие новые интерактивные фильмы Netflix смогут разрабатывать дальше, и будут ли они продолжать развивать технологии и концепции, рассмотренные в этой статье.