2014-09-11 4 views
2

У меня установлен видео-сайт, который обслуживает m3u8 и связанные с ним файлы ts для пользователей. Я не хочу, чтобы медиа-файлы были доступны свободно, так что я сделал это: когда пользователь находится на сайте, в mysql создается сеанс с их IP и токеном; когда они запрашивают какой-либо файл в конкретном субдомене мультимедиа (mp4.domain.com), модуль Nginx auth запрашивает localhost: 8080 с url и прикрепленным токеном в качестве файла cookie запроса, установленного через javascript ... запрашивает базу данных и разрешает/отказывает доступ к файлу зависит от информации о сеансе.Google Cloud Storage Подписанный адрес для СМИ

Теперь это прекрасно работает, накладные расходы составляют от 8 до 20 MS в зависимости от нагрузки на сервер, и нет необходимости манипулировать URL-адресами в PHP при создании ссылки m3u8; OSMF просто получает m3u8 и запрашивает файлы, javascript добавляет маркерный файл cookie и ваш дядя Боба.

Теперь мы переходим на Google Cloud Storage, и проблема, с которой я столкнулся, заключается в том, что я не могу контролировать какой-либо из них ... подписанный URL-адрес для m3u8 достаточно прост, но каждый m3u8 должен быть динамически генерирован с подписанными URL-адресами для каждого ts-файла для каждого разрешения, эскиза и аудио aac (чтобы дать вам представление, случайное видео, которое я выбрал, имеет 1,043 файла) ... это 1,043 разных подписанных URL-адреса для создания, при примерно 6 MS каждый дает 6 секунд всего времени генерации ... что ужасно.

Есть ли альтернативный способ управления этим? Я не слишком увлечен облачным хранилищем API, но я не могу найти ничего другого ... ACL кажутся бесполезными для этого, и единственное, что я могу придумать, - это поворот файлов на ... ежедневный ? ..., чтобы запутать их. Кто-нибудь имел подобную ситуацию или имел представление о том, где я могу начать играть, чтобы решить это?

+0

Есть ли небольшой список m3u8s, к которым имеют доступ многие пользователи? Один из вариантов может состоять в том, чтобы асинхронно генерировать новый m3u8, а затем обслуживать это в течение следующих нескольких часов перед созданием нового. Это может не сработать, если есть миллионы отдельных m3u8. –

+0

@BrandonYarbrough; на данный момент на сайте имеется 678 видеороликов (что соответствует 4068 сумм м3u8s [по одному для каждого из 180 360 6480 720 1080, AAC]). Хотя вы представляете себе хорошую идею ... Я мог бы написать сценарий, который генерирует все m3u8 каждые х часов, отправляйте его на дБ и отталкивайте оттуда при создании ури для проигрывателя ... работоспособное решение ... Я собираюсь поиграть с этим и посмотреть, что я получу. – hdezela

ответ

2

После дополнительных исследований, я пришел к следующему выводу:

Мои первые расчеты, где сделано с помощью инструмента GSUtil Google, который, кажется, ввести много накладных расходов при расчете подписанную URL хэш, например:

GSUtil код: время

gsutil signurl -d 60m /path/to/google.p12 gs://bucket/file 

исполнения: 0,73812007904053

, однако, используя встроенные функции PHP для созда съел подписанный URL гораздо быстрее:

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); 
} 

Время выполнения: 0,0007929801940918

Это все меняет, как работает 2000 итераций кода PHP еще только дает мне время выполнения 1.0643119812012 плюс дополнительно 0.0325711573357 для создания всех файлов m3u8 плюс 0.0039050579071045 для дополнительных 6 итераций для создания подписанных URL-адресов для m3u8s; давая общее время выполнения 1.100788196444004 секунды, причем наибольшая часть зависит от длины видео.

Это на самом деле кажется прекрасным, так как пользователи используются для более длительного «загрузки» или «буферизации» времени для более длинных видеороликов, поэтому дольше чем на 0,5 - 1,5 секунды, когда видео больше, на самом деле это не повлияет на удобство использования.

Как в стороне, в текущем состоянии на сервере имеется 689 видеороликов, в общей сложности 864,138 связанных .ts и .aac-файлов, каждое видео с 6 m3u8s (180,360,480,720,1080, AAC) плюс дополнительный m3u8 для главного плейлиста ... так что для генерации почасового URL для всех видео потребуется (689 [master m3u8] + 864,138 [assets] + 4134 [qual m3u8]) 868,961 итераций кода PHP, общая продолжительность выполнения 467.15262699127 (~ 7 минут), который является управляемым, но спорным с учетом времени выполнения, чтобы динамически генерировать каждый URL-адрес.

Все это использует экземпляр Google Compute n1-highmem-2, который не настолько мощный, поэтому переход на более мощную машину сделает все это еще быстрее.

Но все это привносит еще одно измерение в складку, так как Google (как и все другие) взимает плату за операцию PUT на каждом ковше, поэтому расчет стоимости в порядке. Глядя на нашу статистику за последний месяц, я вижу в общей сложности 447,103 видеороликов (эй, это небольшой сайт), который по предлагаемой схеме создавал бы 7 PUT-операций для каждого видео-удара (6 бит-бит m3u8 + 1 master m3u8), в общей сложности 3,129,721 дополнительных PUT в этом месяце, рассчитывая на стоимость (3129721/10000 * 0,01), дает мне долларовую цифру в размере 3,13 долл. США за эту дополнительную сумму ... небольшую, но может стать проблемой, если сайт станет более популярным. Другое решение (по часовой стрелке для всех) будет генерировать ((689 [master m3u8] + 4134 [qual m3u8]) * 24 [gens per day] * 30 [дней в месяц]) 3,472,560 дополнительных PUTs ..., что примерно то же самое, поэтому я нахожусь в точке безубыточности или близкой к точке безубыточности для выбора между двумя схемами. Мне нужно сделать больше чисел, используя данные предыдущих месяцев, чтобы получить лучшее представление об этом, поскольку одна схема (URL-адрес для каждого) зависит от количества пользователей, а другая (глобальное создание URL-адресов) зависит от количества видео ... и каждый из них имеет совершенно разные способы.

В сущности, используя собственный код, проблема кажется чисто денежной с небольшим вектором кодирования (переписывая код воспроизведения видео или вводить почасовое генерирование URL-адресов). Оба должны быть рассмотрены и сопоставлены, прежде чем принимать окончательное решение.

Несмотря на то, что новый ACL в API облачного хранилища (например, медиа-часть-файл с m3u8 в качестве полезной нагрузки), который может быть привязан к m3u8, сделает все более плавным, чтобы сработать ... есть ли где-нибудь я могу предложить это для команды Google Storage?

- 30/10 Edit: Окончательное решение -

Это окончательное решение, которое я придумал, и это, кажется, работает нормально до сих пор.

Установка:

Nginx на Google Cloud Compute Instance - m3u8.domain.com

  • видео конвертер делает следующее: 1.- FFmpeg для преобразования исходных файлов в 180,360,480,720,1080, AAC-подфайлы 2.- ffmpeg сегментирует файлы в 11-секундные фрагменты (меньше файлов, iOS все еще принимает его) 3.- PHP копирует все медиафайлы в GS-ведро 4.- PHP анализирует сгенерированные файлы m3u8 и создает динамический m3u8 файл 5.- PHP КОПИИ size.m3u8 файлы и файл master.m3u8 в соответствующий каталог на приложенный HDD

  • Новый блок сервера в nginx.conf, который анализирует .m3u8 файлы как PHP 1.- OSMF игрок просит мастер m3u8, JS добавляет сеанс маркера 2.- PHP проверяет маркер сеанса + IP для проверки пользователя 3.- Если подтверждено, вторит текущее видео m3u8 4.- Если не подтверждено, вторит m3u8 говорят, что вы не можете увидеть это видео

процесс, для видеофайла 2:44:08 занимает от 0,7 до 0,9 секунды, почти невидимый для пользователей. Для более коротких видеороликов он экспоненциально крошечный.

Ведро для хранения облаков (mp4domain) - mp4.domain.com

В ведро применяется ACL по умолчанию, который делает все файлы приватными, но доступными для идентификатора Google, используемого для создания подписанных URL-адресов.

Так, один видео имеет следующие файлы:

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, кажется, думает, что это код и не позволит мне отформатировать его иначе)

Таким образом, пишет GS является только один раз, и, поскольку все клиенты считают, что получают простые файлы m3u8, хакерство не должно выполняться на стороне клиента.

Надеюсь, это может помочь кому-то с аналогичными проблемами.

Смежные вопросы