Медиапоток, захваченный WCS, может быть записан при публикации.
Поддерживаемые протоколы:
Форматы записи:
1. Для теста используем демо-сервер demo.flashphoner.com и веб-приложение Stream Recording
https://demo.flashphoner.com/client2/examples/demo/streaming/stream_recording/recording.html
2. Нажмите кнопку "Start". Начнется захват и трансляция потока.
3. Нажмите кнопку "Stop". Трансляция остановится, отобразится ссылка на воспроизведение и скачивание записанного фрагмента
По умолчанию запись потоков включена на стороне WCS-сервера.
Для отключения в конфиг /usr/local/FlashphonerWebCallServer/conf/flashphoner.properties следует добавить
record_streams=false |
Настройка
record_flash_published_streams=true |
включает запись потоков, опубликованных при помощи Flash, RTMP-кодировщика или с другого RTMP-сервера.
Настройка
record_rtsp_streams=true |
включает запись потоков, захваченных с RTSP IP-камер.
По умолчанию, H264 потоки записываются в контейнер MP4, VP8 потоки - в контейнер WebM. Начиная со сборки 5.2.610, H264 потоки могут быть записаны в контейнер MPEG-TS при помощи настройки
record_h264_to_ts=true |
1. VLC до версии 3.0.8 может не играть записи в контейнере TS.
2. При проигрывании в VLC может не работать перемотка.
По умолчанию, имя файла формируется по шаблону, который задается настройкой stream_record_policy_template.
stream_record_policy_template=stream-{mediaSessionId}-{login} |
Доступны следующие элементы шаблона:
Элемент | Описание | Максимальный размер |
---|---|---|
{streamName} | Имя потока | |
{duration} | Длительность файла, только для MP4-записей | |
{startTime} | Время начала записи потока или фрагмента | 20 символов |
{endTime} | Время окончания записи потока или фрагмента | 20 символов |
{startTimeMillis} | Время сервера на момент начала записи потока или фрагмента | 20 символов |
{endTimeMillis} | Время сервера на момент окончания записи потока или фрагмента | 20 символов |
{sessionId} | Идентификатор сессии в кодировке BASE64 | 60 символов |
{mediaSessionId} | Идентификатор медиасессии | 36 символов |
{login} | Логин | 32 символа |
{audioCodec} | Аудиокодек | 4 символа |
{videoCodec} | Видеокодек | 4 символа |
Например, настройка
stream_record_policy_template={streamName} |
означает, что имя файла будет соответствовать имени потока. Поток, опубликованный при помощи ffmpeg
ffmpeg -re -i BigBuckBunny.mp4 -preset ultrafast -acodec aac -vcodec h264 -strict -2 -f flv rtmp://test1.flashphoner.com:1935/live/stream_ffmpeg |
будет записан в файл stream_ffmpeg.mp4.
Расширение файла добавляется в зависимости от параметров потока и контейнера: mp4 для H264+AAC и webm для VP8+opus.
Если имя файла создается из имени потока, в нем могут быть символы, недопустимые к использованию в именах, например, прямой слэш '/'. В этом случае имя файла должно быть закодировано при помощи настройки
encode_record_name=true,HEX |
При этом имя файла будет закодировано шестнадцатиричным числом. Настройка
encode_record_name=true,BASE64 |
кодирует имя файла при помощи BASE64.
Другой способ экранирования недопустимых символов - их удаление при помощи параметра exclude_record_name_characters. По умолчанию
exclude_record_name_characters=/ |
Например, для исключения двоеточия, запятой, точки и слэша необходимо указать
exclude_record_name_characters=:.,/ |
Потоки могут записываться частями заданной длительности или объема при помощи параметра record_rotation. Например, настройка
record_rotation=20 |
определяет длительность фрагмента в 20 секунд, а настройка
record_rotation=10M |
задает объем фрагмента в 10 мегабайт.
Если шаблон имени файла содержит элемент {startTime}, в имя файла подставляется время начала записи фрагмента. Если шаблон содержит элемент {endTime}, в имя файла подставляется время окончания записи фрагмента. Например, при настройках
record_rotation=20 stream_record_policy_template={streamName}-{startTime}-{endTime} |
фрагменты записи потока test
именуются следующим образом
test-1553577643961-1553577663988_1.mp4 test-1553577663989-1553577683997_2.mp4 test-1553577683997-1553577701626_3.mp4 ... |
Фрагменты нумеруются последовательно, начиная с 1. Для новой медиасессии (даже если опубликован поток с таким же именем) нумерация начинается заново, т.е., если статическая часть шаблона не уникальна (например, только имя потока), файлы, записанные ранее, будут перезаписаны поверх.
При необходимости, нумерация может быть отключена настройкой
record_rotation_index_enabled=false |
В этом случае индексы не добавляются и ротация осуществляется в полном соответствии с заданным шаблоном имени файла. При этом, если шаблон не обеспечивает уникальность, файлы, записанные ранее, будут перезаписаны поверх.
Начиная со сборки 5.2.458, время начала, окончания и длительности записи вычисляется по меткам времени кадров потока. При этом, отсчет меток времени RTMP потока всегда начинается с 0, для WebRTC потока браузер фиксирует полную метку времени по данным своих часов.
stream_record_policy_template={streamName}-{startTime}-{endTime}-{duration} |
В сборке 5.2.635 добавлена возможность указать время начала и окончания записи по часам сервера
stream_record_policy_template={streamName}-{startTimeMillis}-{endTimeMillis} |
При этом метки времени в потоке в общем случае будут отличаться от показаний часов сервера.
Для более точного вычисления времени с учетом синхронизации аудио и видео в записи, необходимо включить буферизацию аудиоданных при записи. С этой целью, добавлена настройка
record_audio_buffer_max_size=100 |
По умолчанию, размер буфера установлен в 100 пакетов.
Настройка on_record_hook_script указывает на shell-скрипт, который вызывается по завершении записи потока.
По умолчанию скрипт располагается в каталоге /usr/local/FlashphonerWebCallServer/bin:
on_record_hook_script=/usr/local/FlashphonerWebCallServer/bin/on_record_hook.sh |
но может быть размещен в любом другом месте под другим именем, например:
on_record_hook_script=/opt/on_record.sh |
Этот скрипт можно использовать для копирования или перемещения записи потока из директории WCS_HOME/records в другое место по завершении записи.
Пример:
STREAM_NAME=$1 SRC_FILE=$2 SRC_DIR="/usr/local/FlashphonerWebCallServer/records/" REPLACE_STR="/var/www/html/stream_records/$STREAM_NAME-" DST_FILE="${SRC_FILE/$SRC_DIR/$REPLACE_STR}" cp $SRC_FILE $DST_FILE |
Здесь
Необходимо учитывать длину абсолютного имени файла (с учетом имени каталога), которое будет получено при копировании. Если абсолютное имя целевого файла превышает 255 символов, команда копирования завершится с ошибкой, и скрипт не сработает в соответствии с ожиданиями.
Начиная со сборки 5.2.801, WCS запускается от пользователя 'flashphoner' для большей безопасности. В связи с этим, при перемещении записанных файлов в другой каталог, необходимо разрешить запись в этот каталог. Например, если файлы копируются в каталог /opt/media
STREAM_NAME=$1 FILE_NAME=$2 echo $STREAM_NAME:$FILE_NAME >> /usr/local/FlashphonerWebCallServer/logs/record.log cp $FILE_NAME /opt/media |
необходимо назначить права на запись в этот каталог
sudo chmod o+w /opt/media |
По умолчанию записи потока сохраняются в каталог WCS_HOME/records. Начиная со сборки 5.2.687, каталог для сохранения записей можно изменить при помощи параметра
record_dir=/usr/local/FlashphonerWebCallServer/records |
Если в данной настройке указан не тот каталог, который используется по умолчанию, загрузка записей в примере Stream Recording не будет работать. В этом случае рекомендуется настроить собственный веб-сервер для загрузки файлов записей.
Начиная со сборки 5.2.801, WCS запускается от пользователя 'flashphoner' для большей безопасности. В связи с этим, при изменении данной настройки, необходимо разрешить запись в указанный каталог. как описано выше.
По умолчанию, запись звука ведется с частотой дискретизации 44.1 кГц. При необходимости, это значение можно изменить при помощи параметра
record_audio_codec_sample_rate=48000 |
В данном случае частота дискретизации будет установлена в 48 кГц.
Для того, чтобы файл записи можно было играть во время загрузки (progressive downloading), атом moov
в метаданных записи должен предшествовать атому mdat
. С этой целью в последних сборках добавлена настройка, установленная по умолчанию
mp4_container_moov_first=true |
Для оптимизации процесса сохранения записи на диске и уменьшения количества дисковых операций, предусмотрено резервирование места под атом moov
при создании файла. Эта возможность включается при помощи параметра
mp4_container_moov_first_reserve_space=true |
Размер резервируемой области устанавливается в килобайтах настройкой
mp4_container_moov_reserved_space_size=2048 |
По умолчанию, резервируется 2048 килобайт. Таким образом, если резервирование места под атом moov
включено, размер записанного файла будет не меньше указанного значения, это следует учитывать при настройке ротации записей по размеру.
В сборке 5.2.428 добавлена возможность указать режим битрейта аудио дорожки при записи с использованием кодека FDK. По умолчанию, установлен режим 5 (переменный битрейт в среднем 112 кбит/с). Это значение может быть изменено при помощи настройки
record_fdk_aac_bitrate_mode=5 |
Возможные режимы битрейта:
Необходимо отметить, что воспроизведение записанных файлов с указанием определенного отрезка при помощи модуля nginx ngx_http_mp4_module возможно только при использовании переменного битрейта.
В сборке 5.2.610 добавлена возможность указывать количество каналов звука в записи при помощи настройки
record_audio_codec_channels=2 |
По умолчанию, количество каналов установлено в 2 (стерео). Чтобы записать поток с моно звуком, необходимо указать
record_audio_codec_channels=1 |
При одновременной записи большого количества публикаций сохранение файлов на диск по окончании записи может занимать существенное время. Для того, чтобы ускорить сохранение, в сборке 5.2.639 добавлена возможность задать число процессорных потоков, которые будут заниматься записью, при помощи настройки
file_recorder_thread_pool_max_size=4 |
По умолчанию, обработкой записи занимаются 4 потока. При необходимости, их число может быть увеличено. Отметим, что не рекомендуется устанавливать количество потоков больше, чем имеется процессоров в системе.
Начиная со сборки 5.2.905, для записи VP8 потоков в контейнер webm по умолчанию используется Java-реализация
webm_java_writer_enable=true |
Для данной реализации доступны настройки длительности (в миллисекундах) и размера кластера (в байтах), по достижении которых данные потока записываются в файл на диске
webm_cluster_duration_limit=100000 webm_cluster_size_limit=131072 |
При возникновении проблем с записью, существует возможность переключиться на реализацию на базе ffmpeg
webm_java_writer_enable=false |
При записи потока, данные записываются во временный файл, а затем копируются в файл записи, именованный в соответствии с шаблоном. Начиная со сборки 5.2.963, для размещения временных файлов можно указать отдельный каталог при помощи настройки
record_tmp_dir=/tmp |
Это позволяет, например, помещать временные файлы на RAM-диск, что существенно увеличивает скорость записи.
Процесс WCS должен иметь достаточно прав для записи в каталог для временных файлов, поэтому пользователь flashphoner должен быть назначен владельцем этого каталога. Например, если каталог настроен как
record_tmp_dir=/opt/wcs |
то пользователю flashphoner должны быть назначены права на этот каталог
sudo chown -R flashphoner:flashphoner /opt/wcs |
По умолчанию, временные файлы помещаются в каталог /usr/local/FlashphonerWebCallServer/records
При включении записи потоков на сервере, будет ли записан поток, или нет, зависит от значения параметра record, переданного функции createStream в скрипте публикующего клиента:
Например, в скрипте веб-приложения Stream Recording recording.html, recording.js, содержится следующий код:
function publishStream(session) { var streamName = $('#url').val().split('/')[3]; session.createStream({ name: streamName, display: localVideo, record: true, receiveVideo: false, receiveAudio: false ... }).publish(); } |
В некоторых случаях, необходимо записать поток, который уже транслируется сервером, например, выходной поток микшера. Это можно сделать при помощи REST API. Обратите внимание, что только потоки в статусе "PUBLISHING" могут быть записаны.
REST-запрос должен быть HTTP/HTTPS POST запросом в таком виде:
Здесь:
REST-метод | Пример тела REST-запроса | Пример тела REST-ответа | Статусы ответа | Описание | |
---|---|---|---|---|---|
/stream/startRecording, /recorder/startup |
| 404 - Not found 500 - Internal error | Начать запись потока в указанной медиасессии | ||
/stream/stopRecording, /recorder/terminate |
| 404 - Not found 500 - Internal error | Завершить запись потока в указанной медиасессии | ||
/recorder/find_all |
| 404 - Not found 500 - Internal error | Найти записываемые сессии |
Имя параметра | Описание | Пример |
---|---|---|
mediaSessionId | Идентификатор сессии | 5a072377-73c1-4caf-abd3 |
config | Настройки записи, имеют приоритет над настройками сервера | |
fileTemplate | Шаблон имени файла записи | {streamName}-{startTime}-{endTime} |
rotation | Включает/отключает ротацию файлов и способ нарезки (время или объем) | 20M |
Логика работы записи по требованию выглядит следующим образом:
Например, если необходимо передать точное имя файла для записи потока и отключить ротацию, должен быть передан запрос:
/recorder/startup { "mediaSessionId":"1234567890abcdefgh", "config": { "fileTemplate": "test", "rotation": "disabled" } } |
REST запрос /recorder/find_all возвращает список сессий, записываемых в данный момент. В списке отражаются как записи по требованию, запущенные через REST API, так и записи, инициированные через WebSDK:
[ { "fileName": "003f-1563776713987-{endTime}.mp4", "mediaSessionId": "5af9c820-ac49-11e9-9f06-693cb47c4042" }, { "fileName": "stream-57882100-ac49-11e9-afdd-6752f5be57a9-jtdvnittjkrd8rsc3dnfbger2o.mp4", "mediaSessionId": "57882100-ac49-11e9-afdd-6752f5be57a9" } ] |
Существуют следующие способы узнать имя записанного файла, например, для его скачивания:
1. На сервере имя файла получает скрипт обработки записанных файлов по окончании записи
2. Если имя файла необходимо знать в браузере, шаблон должен быть сформирован таким образом, чтобы в него входили параметры потока, которые могут быть получены при помощи REST API, например
stream_record_policy_template={streamName}-{mediaSessionId} |
3. При использовании WebSDK для записи потока, имя записанного файла можно получить при помощи функции getRecordInfo()
... }).on(STREAM_STATUS.UNPUBLISHED, function (stream) { setStatus(stream.status()); showDownloadLink(stream.getRecordInfo()); onStopped(); }) ... |
Отметим, что при большом размере записи событие STREAM_STATUS.UNPUBLISHED может прийти через значительное время. В сборке 5.2.673 добавлена настройка, которая ограничивает интервал ожидания окончания записи (по умолчанию 15 секунд)
record_stop_timeout=15 |
Записанный файл доступен во встроенном веб-сервере WCS по прямой ссылке вида
https://test.flashphoner.com:8444/client/records/stream.mp4 |
Здесь
По умолчанию, WCS возвращает заголовок
Content-Disposition: inline;filename="stream.mp4" |
в этом случае браузер попытается проиграть файл. Это поведение включается при помощи настройки
record_response_content_disposition_header_value=inline |
Для того, чтобы браузер загружал записанный файл, не пытаясь его проиграть, необходимо установить настройку
record_response_content_disposition_header_value=attachment |
В сборке 5.2.894 добавлена возможность загрузки и воспроизведения указанного фрагмента файла. Для этого необходимо запросить файл с указанием начали и конца фрагмента в секундах
https://test.flashphoner.com:8444/client/records/stream.mp4?start=11&end=60 |
Может быть указано только время начала воспроизведения или только время конца.
Запрошенные фрагменты записываются в тот же каталог, где расположены файлы записей, с добавлением в имени времен начала и конца, например
stream-s11-e60.mp4 |
После загрузки такие файлы не удаляются, если такой же фрагмент запрошен снова, сервер отправит уже существующий фрагмент.
Начиная со сборки 5.2.899, воспроизведение фрагментов поддерживается и для записей только с аудио.
По умолчанию, фрагменты записываются в каталог
/usr/local/FlashphonerWebCallServer/records |
(туда же, куда по умолчанию помещены записи).
В сборке 5.2.957 добавлена возможность указать отдельный каталог для фрагментов при помощи настройки
mp4_cutter_dir=/tmp |
1. Загрузка и воспроизведение фрагментов поддерживается только для MP4 контейнера. При запросе webm файла запись всегда загружается полностью.
2. При указании времени начала фрагмента, воспроизведение может начаться чуть раньше, в зависимости от расположения ключевого фрейма в файле.
В сборке 5.2.1012 добавлена возможность записи нескольких потоков в один файл. В дальнейшем потоки могут быть извлечены из этого файла и смикшированы специальным инструментом. Несколько потоков могут быть записаны только в MP4 контейнер (H264 + AAC). Эта возможность предназначена, например, для записи видеоконференций. В отличие от MCU микшера, здесь микширование работает только при обработке уже записанного файла, и позволяет расходовать меньше ресурсов процессора непосредственно во время проведения конференции.
Запись нескольких потоков управляется по REST API.
REST-запрос должен быть HTTP/HTTPS POST запросом в таком виде:
Здесь:
REST-метод | Пример тела REST-запроса | Пример тела REST-ответа | Статусы ответа | Описание | |
---|---|---|---|---|---|
/multipleRecorder/startup |
| 409 - Conflict 500 - Internal error | Запустить рекордер для записи нескольких потоков | ||
/multipleRecorder/add |
| 404 - Not found 409 - Conflict 500 - Internal error | Добавить в рекордер поток из указанной медиасессии | ||
/multipleRecorder/find_all |
| 404 - Not found 500 - Internal error | Найти все рекордеры | ||
/multipleRecorder/remove |
| 404 - Not found 500 - Internal error | Удалить поток из рекордера | ||
/multipleRecorder/terminate |
| 404 - Not found 500 - Internal error | Остановить рекордер |
Имя параметра | Описание | Пример |
---|---|---|
uri | URI рекордера | multi-recorder://test-record |
mediaSessionId | Идентификатор медиасессии потока | 866a9910-fbfe-11eb-aae4-6f99b0c80a3a |
filename | Имя файла, куда производится запись | multi-recorder___test-record.mp4 |
Имя файла для записи нескольких потоков формируется по шаблону. При этом:
1. Параметр {streamName} подставляется согласно URI рекордера, с заменой символов, не допустимых к использованию в именах файлов, на подчеркивания.
2. Параметры {startTime}, {endTime} не могут быть определены, поскольку зависят от меток времени в потоке, а потоков в данном случае несколько. Поэтому рекомендуется для присвоения метки времени файлу использовать параметры {startTimeMillis}, {endTimeMillis}, которые проставляются согласно часам сервера.
Например, с шаблоном
stream_record_policy_template={streamName}-{startTime}-{startTimeMillis}-{endTime}-{endTimeMillis} |
имя файла для рекордера с URI
"uri": "multi-recorder://test-record" |
будет следующим:
multi-recorder___test-record--1-1628821032180--1-1628821151750.mp4 |
Здесь {startTime}, {endTime} заменены на -1.
По умолчанию файлы записей нескольких потоков сохраняются в каталог WCS_HOME/records. Начиная со сборки 5.2.1088, каталог для сохранения записей можно изменить при помощи параметра
multi_record_dir=/usr/local/FlashphonerWebCallServer/records |
Необходимо, чтобы указанный каталог был доступен для записи, Например, при настройке
multi_record_dir=/opt/media |
права должны быть заданы следующим образом
sudo chmod o+w /opt/media |
Из файла с несколькими потоками внутри по умолчанию может быть воспроизведен только первый поток. Чтобы смотреть все потоки в файле, их необходимо смикшировать. Для этого предназначен инструмент OfflineMP4Mixer, запускаемый следующим образом:
cd /usr/local/FlashphonerWebCallServer/tools ./offline_mixer_tool.sh multi-recorder___test-record--1-1628821032180--1-1628821151750.mp4 |
Настройки микширования задаются в файле /usr/local/FlashphonerWebCallServer/conf/offline_mixer.json. По умолчанию настройки следующие:
{ "hasVideo": "true", "hasAudio": "true", "mixerDisplayStreamName": true } |
Микшированный файл помещается в тот же каталог, где лежит оригинальный файл, к его имени добавляется суффикс _mixed, например
multi-recorder___test-record--1-1628821032180--1-1628821151750_mixed.mp4 |
Пример кадра из микшированного файла
В сборке 5.2.1049 с помощью инструмента для микширования записанных потоков можно получить информацию о дорожках в файле с несколькими потоками. Для этого необходимо запустить его следующим образом:
./offline_mixer_tool.sh --show-tracks-info ../records/multi-recorder___test-record.mp4 |
В этом случае инструмент выведет данные в формате JSON. Например, для файла с записью конференции с двумя участниками:
[ { "durationInMS": "37282", "trackEdits": [ { "endInMs": "14", "type": "pause", "startInMs": "0" }, { "endInMs": "37282", "type": "media", "startInMs": "14" } ], "channels": "2", "trackType": "AUDIO", "trackId": "1", "timescale": "44100", "streamName": "room-09f012-user1-e6ff", "trackCodec": "mp4a", "sampleRate": "44100", "mediaSessionId": "e6ff54e0-1c2a-11ec-90e8-79a2a32f3d9d" }, { "durationInMS": "37336", "trackEdits": [ { "endInMs": "37336", "type": "media", "startInMs": "0" } ], "trackType": "VIDEO", "trackId": "0", "width": "320", "timescale": "90000", "streamName": "room-09f012-user1-e6ff", "trackCodec": "avc1", "mediaSessionId": "e6ff54e0-1c2a-11ec-90e8-79a2a32f3d9d", "height": "240" }, { "durationInMS": "39274", "trackEdits": [ { "endInMs": "100", "type": "pause", "startInMs": "0" }, { "endInMs": "21534", "type": "pause", "startInMs": "100" }, { "endInMs": "39274", "type": "media", "startInMs": "21534" } ], "channels": "2", "trackType": "AUDIO", "trackId": "3", "timescale": "44100", "streamName": "room-09f012-user2-f746", "trackCodec": "mp4a", "sampleRate": "44100", "mediaSessionId": "f74633a1-1c2a-11ec-bba5-af8cf43275a8" }, { "durationInMS": "39303", "trackEdits": [ { "endInMs": "21434", "type": "pause", "startInMs": "0" }, { "endInMs": "39303", "type": "media", "startInMs": "21434" } ], "trackType": "VIDEO", "trackId": "2", "width": "320", "timescale": "90000", "streamName": "room-09f012-user2-f746", "trackCodec": "avc1", "mediaSessionId": "f74633a1-1c2a-11ec-bba5-af8cf43275a8", "height": "240" } ] |
Здесь:
durationInMS - длительность дорожки в миллисекундах
trackType - тип дорожки: AUDIO или VIDEO
Временная шкала дорожки описывается как набор отрезков, построенный в соответствии с атомом MP4 'edit lists`, со следующими параметрами:
По этим данным из файла можно извлечь нужную дорожку при помощи ffmpeg или другого инструмента редактирования MP4 файлов.
Отметим, что, если один и тот же поток был добавлен в рекордер, затем удален из рекордера, и потом снова добавлен, он будет представлен в файле различными дорожками с последовательными идентификаторами trackId, например:
[ { "durationInMS": "78978", "trackEdits": [ { "endInMs": "63050", "type": "pause", "startInMs": "0" }, { "endInMs": "78978", "type": "media", "startInMs": "63050" } ], "channels": "2", "trackType": "AUDIO", "trackId": "3", "timescale": "44100", "streamName": "test", "trackCodec": "mp4a", "sampleRate": "44100", "mediaSessionId": "fbbf5b50-20ee-11ec-bf06-ef6ec6048b2c" }, { "durationInMS": "39708", "trackEdits": [ { "endInMs": "23150", "type": "media", "startInMs": "0" } ], "channels": "2", "trackType": "AUDIO", "trackId": "1", "timescale": "44100", "streamName": "test", "trackCodec": "mp4a", "sampleRate": "44100", "mediaSessionId": "c7bc1460-20ee-11ec-bf06-ef6ec6048b2c" }, { "durationInMS": "39791", "trackEdits": [ { "endInMs": "23233", "type": "media", "startInMs": "0" } ], "trackType": "VIDEO", "trackId": "0", "width": "640", "timescale": "90000", "streamName": "test", "trackCodec": "avc1", "mediaSessionId": "c7bc1460-20ee-11ec-bf06-ef6ec6048b2c", "height": "360" }, { "durationInMS": "63050", "trackEdits": [ { "endInMs": "39791", "type": "pause", "startInMs": "0" }, { "endInMs": "50191", "type": "media", "startInMs": "39791" } ], "trackType": "VIDEO", "trackId": "2", "width": "640", "timescale": "90000", "streamName": "test", "trackCodec": "avc1", "mediaSessionId": "ed3ebda0-20ee-11ec-bf06-ef6ec6048b2c", "height": "360" } ] |
По окончании записи нескольких потоков в один файл, запускается cкрипт обработки, заданный настройкой
on_multiple_record_hook_script=on_multiple_record_hook.sh |
По умолчанию, скрипт запускает offline_mixer_tool.sh, передавая ему на вход имя записанного файла.
Начиная со сборки 5.2.1023, скрипт on_multiple_record_hook.sh по умолчанию записывает в лог /usr/local/FlashphonerWebCallServer/logs/multi-record.log только результат обработки, чтобы снизить нагрузку на диск во время работы инструмента микширования. При необходимости, можно включить подробное логирование для отладки, установив переменную в скрипте
LOGGER_ENABLED=true |
В сборке 5.2.1089 добавлена возможность включить многопоточное кодирование при микшировании записанных потоков. Для этого в файл /usr/local/FlashphonerWebCallServer/conf/offline_mixer.json необходимо добавить параметр
{ ..., "multithreading": true } |
При использовании многопоточного кодирования записанные потоки микшируются в среднем в два раза быстрее по сравнению с однопоточным.
1. Максимальная длина имени файла во всех актуальных файловых системах Linux ограничена 255 символами. При создании файла записи, имя будет сокращено до данного предела, включая расширение и номер части, если включена ротация.
2. При записи потоков, опубликованных в конференции, ротация будет автоматически отключена, в противном случае полученные файлы будет невозможно объединить.
3. Дата создания файла записывается в метаданные только в контейнере MP4.
4. Скрипт обработки записанных файлов требует повышения прав для копирования и других операций над файлами записей на виртуальных машинах Amazon
Симптомы: операции над записанными файлами не выполняются
Решение: использовать sudo для файловых операций и вызова внешних скриптов, если WCS установлен на виртуальной машине Amazon, например
sudo cp $SRC_FILE $DST_FILE |
5. На серверах небольшой мощности, запись двухканального звука приводит к росту нагрузки на процессор и к задержкам при одновременной записи нескольких потоков
Симптомы: при одновременной записи нескольких потоков, загрузка всех процессорных ядер достигает 100%, при завершении публикации потоков запись завершается с большой задержкой
Решение: отключить запись двухканального звука
record_audio_codec_channels=1 |
6. При публикации H264 потока из браузера Firefox на некоторых Android устройствах может портиться запись, при нормальном проигрывании этого же потока по WebRTC
Симптомы: при публикации потока из Android Firefox запись не проигрывается либо испорчена, файл имеет малый размер
Решение:
a) использовать VP8 для публикации потока из Android Firefox
b) использовать на этом устройстве Chrome или другой браузер для публикации
7. Некоторые Android устройства публикуют WebRTC H264 поток с профилем High, даже если этого профиля нет в SDP при установке WebRTC соединения
Симптомы: в данных файла записи опубликованного потока отображается профиль High
Решение: если возникают проблемы при проигрывании записей потоков, опубликованных с профилем High, перекодировать эти записи, например, при помощи ffmpeg, запуская постобработку скриптом on_record_hook.sh
8. Первая запись после запуска сервера может быть повреждена, если Java машина не успевает инициализировать необходимые модули
Симптомы: длительный фриз в начале первой записи после запуска сервера
Решение:
a) обновить WCS до сборки 5.2.1105
b) если используется сборка 5.2.1105 и новее, убедиться, что в настройках включена предварительная инициализацию модулей WebRTC-стека при старте сервера
webrtc_pre_init=true |