Questa pagina spiega come criptare i contenuti dei live streaming. L'API Live Streamm non crea né gestisce direttamente chiavi o licenze di crittografia. Devi invece utilizzare un provider di gestione dei diritti digitali (DRM) di terze parti per queste funzionalità. Una volta create le chiavi di crittografia per i tuoi contenuti multimediali, passale all'API Live Stream utilizzando Secret Manager.
Le impostazioni di crittografia sono specificate nelle
Channel
impostazioni. Una volta avviato lo streaming, la pipeline video dell'API Live Stream
inizia a criptare i tuoi contenuti. Il manifest di output include le informazioni
necessarie per decriptare i contenuti nel media player che preferisci.
Configurazioni supportate
Protocollo di streaming | Container | Sistema DRM | Schema di crittografia |
---|---|---|---|
HLS | TS | ClearKey | aes128 |
HLS | TS | ClearKey | sampleAes |
HLS | TS | FairPlay | sampleAes |
HLS | fMP4 | FairPlay | mpegCenc cbcs only |
MPEG-DASH | fMP4 | ClearKey | mpegCenc cenc o cbcs |
MPEG-DASH | fMP4 | Widevine | mpegCenc cenc o cbcs |
HLS | fMP4 | Widevine | mpegCenc cenc o cbcs |
MPEG-DASH | fMP4 | PlayReady | mpegCenc cenc o cbcs |
HLS | fMP4 | PlayReady | mpegCenc cenc o cbcs |
Aggiungi la chiave di crittografia a Secret Manager
Prima di iniziare, crea le chiavi di crittografia utilizzando il provider DRM di terze parti che preferisci.
L'API Live Stream richiede che il secret contenga la chiave di crittografia nel seguente formato JSON, insieme ad altre informazioni necessarie.
Per una descrizione di ogni campo, consulta la documentazione del protocollo DRM. Tieni presente che devi convertire da snake case a camel case per il formato JSON.
Esempio di struttura JSON
{
"encryptionKeys": [
{
// Key for FairPlay configuration.
"keyId": "d569cb35bd0548c7a99d92feb381df13",
"key": "f1967daca83e81f38d80aa741e7b32c2",
"iv": "8d80aa741e7b32c2f1967daca83e81f3",
"keyUri": "skd://d569cb35bd0548c7a99d92feb381df13",
"matchers": [
{
"muxStreams": ["ts_fairplay"]
}
]
},
{
// Key for Widevine configurations.
"keyId": "44ec248b048c43a6a6ee58a752c6f9f8",
"key": "f1967daca83e81f38d80aa741e7b32c2",
"keyUri": "skd://44ec248b048c43a6a6ee58a752c6f9f8",
"matchers": [
{
"muxStreams": [
"fmp4_widevine_cenc_video",
"fmp4_widevine_cenc_audio",
"fmp4_widevine_cbcs_video",
"fmp4_widevine_cbcs_audio"
]
}
]
},
{
// Key for PlayReady configurations.
"keyId": "8beed229709f480bb6004ec0f33e82d1",
"key": "ad20cd838f354dcc8a77c443d08ff09f",
"keyUri": "skd://8beed229709f480bb6004ec0f33e82d1",
"matchers": [
{
"muxStreams": [
"fmp4_playready_cenc_video",
"fmp4_playready_cenc_audio",
"fmp4_playready_cbcs_video",
"fmp4_playready_cbcs_audio"
]
}
]
},
{
// Key for all ClearKey configurations.
"keyId": "3d9dccb479c64adbb6e514790caa7822",
"key": "f1967daca83e81f38d80aa741e7b32c2",
"keyUri": "https://example.com/keys/3d9dccb479c64adbb6e514790caa7822.bin",
"iv": "8d80aa741e7b32c2f1967daca83e81f3"
// No `matchers` field. This is the default key to use when none of the keys above match.
}
]
}
Se la configurazione della crittografia (ad esempio FairPlay) richiede un vettore di inizializzazione (IV) esplicito, ma non è incluso, l'API utilizzerà il valore di keyId
per il valore di iv
.
Per aggiungere la chiave di crittografia, esegui una delle seguenti operazioni:
Aggiungi e configura manualmente le chiavi. Utilizza i dati JSON precedenti, aggiungi la chiave di crittografia a Secret Manager seguendo i passaggi descritti in Creare un secret.
Implementa un
key publisher
che recupera le chiavi di crittografia necessarie e le scrive in Secret Manager come versioni del secret. Visualizza un'implementazione di esempio che viene eseguita come funzione Cloud Run.
Poi, procedi nel seguente modo per configurare la chiave di crittografia:
- Configura le autorizzazioni IAM sul secret in modo che l'API Live Stream
possa accedere ai contenuti del secret. Per farlo, concedi il ruolo
secretmanager.secretAccessor
all'account di servizioservice-PROJECT_NUMBER@gcp-sa-livestream.iam.gserviceaccount.com
(in modo simile a come l'account di servizio ha accesso ai tuoi bucket Cloud Storage). - Trova il nome della risorsa della versione del secret che hai creato (ad esempio,
projects/PROJECT_NUMBER/secrets/SECRET_ID/versions/VERSION_ID
). Ti serve questo nome per configurare il canale.
Configurare il canale
Le impostazioni di crittografia vengono specificate utilizzando gli oggetti nell'array
encryptions
a livello di Channel
. A ogni configurazione diversa viene assegnato un identificatore univoco
(id
). Ogni muxStream
utilizza un
identificatore per indicare quale configurazione di crittografia utilizzare oppure omette il
campo per rimanere non criptato.
Formato JSON
{
// other channel settings …
"encryptions": [
{
// Identifier for this encryption configuration, to be specified in muxStream(s).
"id": string,
// Configuration for secrets stored in Google Secret Manager.
"secretManagerKeySource": {
// The name of the Secret Version containing the encryption key.
// `projects/{project}/secrets/{secret_id}/versions/{version_number}`
// Using {version_number} of `latest` is not supported.
"secretVersion": string
},
// DRM system(s) that will be used. At least one must be specified. If a DRM system
// is omitted, it will be considered disabled.
"drmSystems": {
// Widevine configuration.
"widevine": {},
// FairPlay configuration.
"fairplay": {},
// PlayReady configuration.
"playready": {},
// ClearKey configuration.
"clearkey": {}
},
// Union field encryption_mode can be only one of the following:
// Configuration for HLS AES-128 encryption.
"aes128": {},
// Configuration for HLS SAMPLE-AES encryption.
"sampleAes": {},
// Configuration for MPEG-DASH Common Encryption (MPEG-CENC).
"mpegCenc": {
// Specify the encryption scheme. Supported schemes:
// - `cenc` - AES-CTR subsample
// - `cbcs`- AES-CBC subsample pattern
"scheme": string
}
// End of list of possible types for union field encryption_mode.
}
// Any other encryption configurations.
],
"muxStreams": [
{
// Unique identifier for the muxStream.
"key": string,
// Identifier of the encryption configuration for the muxStream.
"encryptionId": string
// … other muxStream settings.
}
// Other muxStreams.
],
// Other channel settings.
}
Esempio (ClearKey)
L'esempio seguente configura muxStream AES-128 e SAMPLE-AES nei manifest HLS e muxStream MPEG-CENC (cenc e cbcs) nei manifest DASH:
"elementaryStreams": [
{
"key": "es_video",
"videoStream": {
"h264": {
"profile": "main",
"heightPixels": 600,
"widthPixels": 800,
"bitrateBps": 1000000,
"frameRate": 60,
},
},
},
{
"key": "es_audio",
"audioStream": {
"codec": "aac",
"channelCount": 2,
"bitrateBps": 160000
}
}
],
"encryptions": [
{
"id": "aes-128",
"secretManagerKeySource": {
"secretVersion": "projects/12345/secrets/key-1/versions/1"
},
"drmSystems": {"clearkey": {}},
"aes128": {}
},
{
"id": "sample-aes",
"secretManagerKeySource": {
"secretVersion": "projects/12345/secrets/key-1/versions/1"
},
"drmSystems": {"clearkey": {}},
"sampleAes": {}
},
{
"id": "cenc",
"secretManagerKeySource": {
"secretVersion": "projects/12345/secrets/key-1/versions/1"
},
"drmSystems": {"clearkey": {}},
"mpegCenc": {
"scheme": "cenc"
}
},
{
"id": "cbcs",
"secretManagerKeySource": {
"secretVersion": "projects/12345/secrets/key-1/versions/1"
},
"drmSystems": {"clearkey": {}},
"mpegCenc": {
"scheme": "cbcs"
}
}
],
"muxStreams": [
{
"key": "ts_aes128",
"container": "ts",
"elementaryStreams": ["es_video", "es_audio"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "aes-128"
},
{
"key": "ts_sampleaes",
"container": "ts",
"elementaryStreams": ["es_video", "es_audio"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "sample-aes"
},
{
"key": "fmp4_cenc_video",
"container": "fmp4",
"elementaryStreams": ["es_video"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "cenc"
},
{
"key": "fmp4_cenc_audio",
"container": "fmp4",
"elementaryStreams": ["es_audio"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "cenc"
},
{
"key": "fmp4_cbcs_video",
"container": "fmp4",
"elementaryStreams": ["es_video"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "cbcs"
},
{
"key": "fmp4_cbcs_audio",
"container": "fmp4",
"elementaryStreams": ["es_audio"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "cbcs"
}
],
"manifests": [
{
"key": "manifest_aes128_hls",
"fileName": "manifest_aes128.m3u8",
"type": "HLS",
"muxStreams": ["ts_aes128"],
"maxSegmentCount": 10
},
{
"key": "manifest_sampleaes_hls",
"fileName": "manifest_sampleaes.m3u8",
"type": "HLS",
"muxStreams": ["ts_sampleaes"],
"maxSegmentCount": 10
},
{
"key": "manifest_cenc_dash",
"fileName": "manifest_cenc.mpd",
"type": "DASH",
"muxStreams": ["fmp4_cenc_video", "fmp4_cenc_audio"],
"maxSegmentCount": 10
},
{
"key": "manifest_cbcs_dash",
"fileName": "manifest_cbcs.mpd",
"type": "DASH",
"muxStreams": ["fmp4_cbcs_video", "fmp4_cbcs_audio"],
"maxSegmentCount": 10
}
]
Esempio (FP/PR/Widevine)
L'esempio seguente configura muxStream FairPlay/SAMPLE-AES, Widevine/MPEG-CENC (cenc e cbcs) e PlayReady/MPEG-CENC (cenc e cbcs). I muxStream Widevine e PlayReady sono inclusi nei manifest HLS e DASH.
"elementaryStreams": [
{
"key": "es_video",
"videoStream": {
"h264": {
"profile": "main",
"heightPixels": 600,
"widthPixels": 800,
"bitrateBps": 1000000,
"frameRate": 60,
},
},
},
{
"key": "es_audio",
"audioStream": {
"codec": "aac",
"channelCount": 2,
"bitrateBps": 160000
}
}
],
"encryptions": [
{
"id": "fairplay",
"secretManagerKeySource": {
"secretVersion": "projects/12345/secrets/key-1/versions/1"
},
"drmSystems": {"fairplay": {}},
"sampleAes": {}
},
{
"id": "widevine-cenc",
"secretManagerKeySource": {
"secretVersion": "projects/12345/secrets/key-1/versions/1"
},
"drmSystems": {"widevine": {}},
"mpegCenc": {
"scheme": "cenc"
}
},
{
"id": "widevine-cbcs",
"secretManagerKeySource": {
"secretVersion": "projects/12345/secrets/key-1/versions/1"
},
"drmSystems": {"widevine": {}},
"mpegCenc": {
"scheme": "cbcs"
}
},
{
"id": "playready-cenc",
"secretManagerKeySource": {
"secretVersion": "projects/12345/secrets/key-1/versions/1"
},
"drmSystems": {"playready": {}},
"mpegCenc": {
"scheme": "cenc"
}
},
{
"id": "playready-cbcs",
"secretManagerKeySource": {
"secretVersion": "projects/12345/secrets/key-1/versions/1"
},
"drmSystems": {"playready": {}},
"mpegCenc": {
"scheme": "cbcs"
}
}
],
"muxStreams": [
{
"key": "ts_fairplay",
"container": "ts",
"elementaryStreams": ["es_video", "es_audio"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "fairplay"
},
{
"key": "fmp4_widevine_cenc_video",
"container": "fmp4",
"elementaryStreams": ["es_video"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "widevine-cenc"
},
{
"key": "fmp4_widevine_cenc_audio",
"container": "fmp4",
"elementaryStreams": ["es_audio"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "widevine-cenc"
},
{
"key": "fmp4_widevine_cbcs_video",
"container": "fmp4",
"elementaryStreams": ["es_video"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "widevine-cbcs"
},
{
"key": "fmp4_widevine_cbcs_audio",
"container": "fmp4",
"elementaryStreams": ["es_audio"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "widevine-cbcs"
},
{
"key": "fmp4_playready_cenc_video",
"container": "fmp4",
"elementaryStreams": ["es_video"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "playready-cenc"
},
{
"key": "fmp4_playready_cenc_audio",
"container": "fmp4",
"elementaryStreams": ["es_audio"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "playready-cenc"
},
{
"key": "fmp4_playready_cbcs_video",
"container": "fmp4",
"elementaryStreams": ["es_video"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "playready-cbcs"
},
{
"key": "fmp4_playready_cbcs_audio",
"container": "fmp4",
"elementaryStreams": ["es_audio"],
"segmentSettings": {"segmentDuration": "2s"},
"encryptionId": "playready-cbcs"
}
],
"manifests": [
{
"key": "manifest_fairplay_hls",
"fileName": "manifest_fairplay.m3u8",
"type": "HLS",
"muxStreams": ["ts_fairplay"],
"maxSegmentCount": 10
},
{
"key": "manifest_widevine_cenc_hls",
"fileName": "manifest_widevine_cenc.m3u8",
"type": "HLS",
"muxStreams": ["fmp4_widevine_cenc_video", "fmp4_widevine_cenc_audio"],
"maxSegmentCount": 10
},
{
"key": "manifest_widevine_cbcs_hls",
"fileName": "manifest_widevine_cbcs.m3u8",
"type": "HLS",
"muxStreams": ["fmp4_widevine_cbcs_video", "fmp4_widevine_cbcs_audio"],
"maxSegmentCount": 10
},
{
"key": "manifest_widevine_cenc_dash",
"fileName": "manifest_widevine_cenc.mpd",
"type": "DASH",
"muxStreams": ["fmp4_widevine_cenc_video", "fmp4_widevine_cenc_audio"],
"maxSegmentCount": 10
},
{
"key": "manifest_widevine_cbcs_dash",
"fileName": "manifest_widevine_cbcs.mpd",
"type": "DASH",
"muxStreams": ["fmp4_widevine_cbcs_video", "fmp4_widevine_cbcs_audio"],
"maxSegmentCount": 10
},
{
"key": "manifest_playready_cenc_hls",
"fileName": "manifest_playready_cenc.m3u8",
"type": "HLS",
"muxStreams": ["fmp4_playready_cenc_video", "fmp4_playready_cenc_audio"],
"maxSegmentCount": 10
},
{
"key": "manifest_playready_cbcs_hls",
"fileName": "manifest_playready_cbcs.m3u8",
"type": "HLS",
"muxStreams": ["fmp4_playready_cbcs_video", "fmp4_playready_cbcs_audio"],
"maxSegmentCount": 10
},
{
"key": "manifest_playready_cenc_dash",
"fileName": "manifest_playready_cenc.mpd",
"type": "DASH",
"muxStreams": ["fmp4_playready_cenc_video", "fmp4_playready_cenc_audio"],
"maxSegmentCount": 10
},
{
"key": "manifest_playready_cbcs_dash",
"fileName": "manifest_playready_cbcs.mpd",
"type": "DASH",
"muxStreams": ["fmp4_playready_cbcs_video", "fmp4_playready_cbcs_audio"],
"maxSegmentCount": 10
}
]
Una volta che conosci la configurazione JSON che vuoi utilizzare, crea un canale come di consueto.
Avviare lo streaming
Una volta creato il canale, avvialo e invia il flusso di input.
Quando il canale viene avviato, l'API Live Stream recupera la chiave di crittografia
identificata da secretVersion
da Secret Manager. Se l'API Live Stream non è in grado di recuperare la chiave o la chiave è in un formato non riconoscibile, lo stato del canale diventa STREAMING_ERROR
. Se la chiave
viene recuperata correttamente, lo stato del canale diventa AWAITING_INPUT
come di consueto.
Una volta iniziato lo streaming, l'API Live Stream inizia a criptare i contenuti di output in base alla configurazione fornita al momento della creazione.
Monitorare l'output
I flussi di output criptati contengono manifest modificati con le informazioni necessarie per decriptare i contenuti per la riproduzione.
Esempi di manifest
I seguenti manifest mostrano le informazioni necessarie per decriptare i contenuti associati.
HLS AES-128/ClearKey
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="https://example.com/keys/3d9dccb479c64adbb6e514790caa7822.bin",IV=0x8d80aa741e7b32c2f1967daca83e81f3
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:22.870Z
#EXTINF:2.576778
segment-0000000000.ts
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:25.447Z
#EXTINF:2.000000
segment-0000000001.ts
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:27.447Z
#EXTINF:2.000000
segment-0000000002.ts
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:29.447Z
#EXTINF:2.000000
segment-0000000003.ts
HLS SAMPLE-AES/FairPlay
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://d569cb35bd0548c7a99d92feb381df13",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:22.870Z
#EXTINF:2.576778
segment-0000000000.ts
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:25.447Z
#EXTINF:2.000000
segment-0000000001.ts
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:27.447Z
#EXTINF:2.000000
segment-0000000002.ts
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:29.447Z
#EXTINF:2.000000
segment-0000000003.ts
HLS MPEG-CENC/Widevine
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="data:text/plain;base64,AAAAOHBzc2gAAAAA7e+LqXnWSs6jyCfSEAB3Gcrj/8kFtioyiVbJMh9I49yVmwY=",KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",KEYFORMATVERSIONS="1"
#EXT-X-MAP:URI="segment-initialization_segment_0000000000.m4s"
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:22.870Z
#EXTINF:2.576778
segment-0000000000.m4s
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:25.447Z
#EXTINF:2.000000
segment-0000000001.m4s
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:27.447Z
#EXTINF:2.000000
segment-0000000002.m4s
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T20:08:29.447Z
#EXTINF:2.000000
segment-0000000003.m4s
DASH MPEG-CENC/Widevine
<AdaptationSet segmentAlignment="true" maxWidth="800" maxHeight="600">
<Representation mimeType="video/mp4" id="fmp4_widevine_cenc_video" codecs="avc1.4d001f">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="44ec248b-048c-43a6-a6ee-58a752c6f9f8"/>
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" value="Widevine">
<cenc:pssh>AAAAOHBzc2gAAAAA7e+LqXnWSs6jCfc1R0h7QAAABgSEAB3Gcrj/8kFklokiVbJMh9VmwY=</cenc:pssh>
</ContentProtection>
</Representation>
</AdaptationSet>
<AdaptationSet segmentAlignment="true" mimeType="audio/mp4" id="1" label="fmp4_widevine_cenc_audio">
<Representation id="fmp4_widevine_cenc_audio" codecs="mp4a.40.2">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="44ec248b-048c-43a6-a6ee-58a752c6f9f8"/>
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" value="Widevine">
<cenc:pssh>AAAAOHBzc2gAAAAA7e+LqXnWSs6jCfc1R0h7QAAABgSEAB3Gcrj/8kFklokiVbJMh9VmwY=</cenc:pssh>
</ContentProtection>
</Representation>
</AdaptationSet>
Giocatori consigliati
I player basati su HLS.js
sono consigliati
per la decrittografia HLS/TS. Per la decriptografia DASH/fMP4, sono consigliati i lettori basati su Shaka Player.
Lo schema "cenc" di PlayReady è supportato su macchine fisiche con Windows 10 con il browser Microsoft Edge, Xbox One (versione 1703 o precedente) e alcuni dispositivi non Windows (ad esempio, smart TV). Lo schema "cbcs" di PlayReady è supportato solo su Xbox One versione 1709 o successive. Per ulteriori informazioni, consulta Modalità di crittografia dei contenuti PlayReady.
Aggiornare la chiave di crittografia
Puoi impostare il tuo canale in modo che utilizzi nuove chiavi di crittografia senza interrompere lo stream o riavviare il canale.
Per aggiornare le chiavi, aggiungi prima le nuove chiavi a Secret Manager. Le nuove
chiavi possono essere una nuova versione del secret esistente o un nuovo secret. Se
crei un nuovo secret, assicurati che l'API Live Stream disponga del
ruolo secretmanager.secretAccessor
per quel secret.
Dopo aver inserito le nuove chiavi in Secret Manager, crea un evento di aggiornamento delle crittografie. Vengono aggiornate tutte le impostazioni di crittografia specificate nel corpo della richiesta. Tutte le impostazioni non specificate rimangono invariate.