Après plus de recherche, je suis venu à la conclusion suivante:
Mes premiers calculs lorsqu'ils sont effectués en utilisant l'outil de gsutil de Google, qui semble présenter beaucoup de frais généraux lors du calcul d'un hachage URL signé, par exemple:
code gsutil:
gsutil signurl -d 60m /path/to/google.p12 gs://bucket/file
temps d'exécution: 0,73812007904053
, cependant, en utilisant des fonctions PHP natives pour cre mangé une URL signé est beaucoup plus rapide:
Code PHP:
function storageURL($bucket,$archivo) {
$expires = time()+60;
$to_sign = ("GET\n\n\n".$expires."\n/".$bucket.'/'.$archivo);
$fp = fopen('/path/to/google.pem', 'r');
$priv_key = fread($fp, 8192);
fclose($fp);
$pkeyid = openssl_get_privatekey($priv_key);
if(!openssl_sign($to_sign,$signature,$pkeyid,'sha256')) {
$signature = 'sinfirma';
} else {
$signature = urlencode(base64_encode($signature));
}
return ('https://'.$bucket.'.storage.googleapis.com/'.$archivo.'[email protected]&Expires='.$expires.'&Signature='.$signature);
}
Temps d'exécution: ,0007929801940918
Cela change tout, en cours d'exécution 2000 itérations du code PHP me donne encore qu'un temps d'exécution de 1.0643119812012 plus 0,0325711573357 supplémentaire pour la création de tous les fichiers m3u8 plus 0.0039050579071045 pour 6 itérations supplémentaires pour créer les URL signées pour les m3u8s; donnant un temps d'exécution total de 1.100788196444004 secondes, la plus grande partie dépendant de la longueur de la vidéo. Cela semble vraiment bien, car les utilisateurs sont habitués à des durées de "chargement" ou de "mise en mémoire tampon" plus longues pour les vidéos plus longues, de sorte que les ~ 0.5 - ~ 1.5 secondes supplémentaires lorsque la vidéo est plus longue n'affecteront pas vraiment la convivialité. En passant, dans l'état actuel, il y a actuellement 689 vidéos sur le serveur, avec un total de 864138 fichiers .ts et .aac liés, chaque vidéo ayant 6 m3u8s (180,360,480,720,1080, AAC) plus un m3u8 pour la playlist principale ... donc générer une url horaire pour toutes les vidéos nécessiterait (689 [master m3u8] + 864 138 [assets] + 4134 [qual m3u8]) 868 961 itérations du code PHP, soit une durée totale de 467.15262699127 (~ 7 minutes), ce qui est gérable mais discutable compte tenu du temps d'exécution pour générer dynamiquement chaque URL. Tout ceci utilise une instance de Google Compute n1-highmem-2, qui n'est pas très puissante, donc passer à une machine plus puissante rendra tout cela encore plus rapide. Mais tout cela apporte une autre dimension dans le pli, comme Google (comme tous les autres le font) charge par opération PUT sur chaque seau, donc un calcul des coûts est en ordre. En regardant nos statistiques pour le mois dernier, je vois un total de 447.103 jeux vidéo au total (hé, c'est un petit site), qui, selon le schéma proposé, aurait généré 7 opérations PUT pour chaque hit vidéo (6 bitrate m3u8 + 1 master m3u8), un total de 3.129.721 PUT supplémentaires ce mois-ci, calculant pour le coût (3129721/10000 * 0.01) me donne un chiffre de 3,13 $ de coût supplémentaire pour ce ... petit mais pourrait devenir un problème si le site devient plus populaire. L'autre solution (URL signées à l'heure pour tout le monde) générerait ((689 [maître m3u8] + 4134 [qual m3u8]) * 24 [gens par jour] * 30 [jours par mois]) 3 472 560 PUT supplémentaires ... ce qui est grosso modo la même chose, donc je suis à ou près du seuil de rentabilité (coût-sage) pour choisir entre les deux régimes. Je dois faire plus de chiffres ici en utilisant les données des mois précédents pour avoir une meilleure idée car un schéma (URL par hit) dépend du nombre d'utilisateurs et l'autre (génération d'URL globale) dépend de la quantité de vidéos ... et ils évoluent chacun de manière totalement différente. En gros, en utilisant du code natif, le problème semble être purement monétaire avec un petit vecteur de codage (réécriture du code de lecture vidéo par opposition à la génération d'une URL horaire). Les deux doivent être examinés et comparés avant de prendre une décision finale. Cependant, une nouvelle liste de contrôle d'accès dans l'API Cloud Storage (disons fichier multimédia avec m3u8 comme charge utile) pouvant être liée à un m3u8 rendrait tout plus facile à résoudre ... y a-t-il un endroit que je pourrais proposer? ceci à l'équipe de Google Storage?
- 30/10 Edit: Solution finale -
C'est la solution finale, je suis venu avec, et il semble fonctionner très bien jusqu'à présent.
Configuration:
Nginx sur Google Cloud Compute instance - m3u8.domain.com
Le convertisseur vidéo effectue les opérations suivantes: ffmpeg pour convertir 1.- fichiers source à 180,360,480,720,1080, Sous-dossiers AAC 2.- ffmpeg segmente les fichiers en 11 morceaux (moins de fichiers, iOS les accepte toujours) 3.- PHP copie tous les fichiers média dans le seau GS 4.- PHP analyse les fichiers m3u8 générés et crée une dynamique fichier m3u8 5.- PHP Les fichiers de copies et fichier master.m3u8 à répertoire approprié sur le disque dur attaché
Nouveau bloc serveur nginx.conf qui parse .m3u8 fichiers PHP en tant que joueur OSMF demandes 1.- maître m3u8, JS ajoute jeton de session PHP chèques 2.- jeton de session + IP pour valider l'utilisateur Si elle est validée 3.-, echos m3u8 vidéo actuelle 4.- Si non validée, echos m3u8 dire que vous n'êtes pas autorisé à voir cette vidéo
Le processus, pour un fichier vidéo 2:44:08 prend entre 0,7 - 0,9 secondes, presque invisible pour les utilisateurs. Pour les vidéos plus courtes, il est exponentiellement minuscule.
Seau de stockage Cloud (mp4domain) - mp4.domain.com
Le bucket a une liste de contrôle d'accès par défaut appliquée qui rend tous les fichiers privés mais accessibles à l'ID Google utilisé pour générer les URL signées.
Ainsi, une seule vidéo a les fichiers suivants:
SERVER/nginx/mp4/uniqid/uniqid.m3u8
SERVER/nginx/mp4/uniqid/180p/stream.m3u8
SERVER/nginx/mp4/uniqid/360p/stream.m3u8
SERVER/nginx/mp4/uniqid/480p/stream.m3u8
SERVER/nginx/mp4/uniqid/720p/stream.m3u8
SERVER/nginx/mp4/uniqid/1080p/stream.m3u8
SERVER/nginx/mp4/uniqid/audio/stream.m3u8
GS/bucketmp4/uniqid/180p/segment##.ts
GS/bucketmp4/uniqid/360p/segment##.ts
GS/bucketmp4/uniqid/480p/segment##.ts
GS/bucketmp4/uniqid/720p/segment##.ts
GS/bucketmp4/uniqid/1080p/segment##.ts
GS/bucketmp4/uniqid/audio/segment##.aac
(SO Semble penser que c'est le code et ne me laisse pas formater autrement)
De cette façon, écrit à GS sont Une seule fois, et puisque tous les clients pensent recevoir des fichiers m3u8, aucun piratage ne doit être effectué côté client.
Espérons que cela peut aider quelqu'un avec des problèmes similaires.
Y a-t-il une petite liste de m3u8 auxquels de nombreux utilisateurs ont accès? Une option pourrait être de générer un nouveau m3u8 de manière asynchrone, puis de le servir pendant les prochaines heures avant de générer un nouveau. Cela pourrait ne pas fonctionner s'il y a des millions de m3u8 distincts. –
@BrandonYarbrough; à ce jour, il y a 678 vidéos au total sur le site (ce qui équivaut à 4 068 m3u8s [un pour chacun des 180 360 602 720, 1080 AAC]). Bien que vous posiez une bonne idée ... je pourrais écrire un script qui génère toutes les m3u8s toutes les x heures, poster cela au dB et tirer de là en générant uris pour le joueur ... une solution réalisable ... Je suis aller jouer avec ça et voir ce que je reçois. – hdezela