...
- MP4 для кодеков H.264 + AAC
- WebM для кодека кодеков VP8 + Vorbis
- WebM для кодеков H264 + opus (начиная со сборки 2.0.2001)
- TS для кодеков H.264 + ADTS
- MKV (начиная со сборки 5.2.1190)
...
Обратите внимание, что потоки, которые не содержат видео дорожки, всегда записываются в MP4 контейнер (кодек AAC).
Начиная со сборки 2.0.2001, для записи WebRTC потоков H264+opus поддерживается также контейнер WebM
Code Block | ||
---|---|---|
| ||
record_formats=h264-webm,vp8-webm |
Запись потоков в контейнер MPEG-TS
...
Если к ошибке привел определенный кадр в медиапотоке, этот и последующие кадры не будут записаны, до успешного получения очередного ключевого кадра.
Клиентская часть
При включении записи потоков на сервере, будет ли записан поток, или нет, зависит от значения параметра record, переданного функции createStream в скрипте публикующего клиента:
- true - поток, опубликованный с использованием этого клиента, будет записан;
- false - поток не будет записан.
Например, в скрипте веб-приложения Stream Recording recording.html, recording.js, содержится следующий код:
...
language | js |
---|---|
theme | RDark |
...
Запись актуальных данных в заголовок MP4 контейнера
В сборке 5.2.1990 добавлена возможность периодической записи актуальных данных в заголовок MP4 контейнера
Code Block | ||
---|---|---|
| ||
mp4_container_moov_first_reserve_space=true
mp4_container_write_header_on_fly=true |
В этом случае данные заголовка периодически обновляются в соответствии с записанными в файл медиаданными. Период обновления задается настройкой в секундах
Code Block | ||
---|---|---|
| ||
mp4_container_write_header_on_fly_interval=5 |
Это позволяет проиграть записанный файл даже при внезапной остановке записи в случае ошибки. Данные будут доступны для проигрывания в соответствии с заголовком.
Ротация при заполнении заголовка MP4 контейнера
Начиная со сборки 5.2.2012, если во время записи заполняется MOOV атом в заголовке MP4 контейнера, запись автоматически ротируется по максимально допустимому объему данных. Например, при публикации потока 1920x1080 с битрейтом 3 Мбит/c, 30 fps и записи этого потока с настройками
Code Block | ||
---|---|---|
| ||
mp4_container_moov_first_reserve_space=true
mp4_container_moov_reserved_space_size=2048 |
длительность одной части составит около 22 минут, размер одной части около 510 Мб.
Клиентская часть
При включении записи потоков на сервере, будет ли записан поток, или нет, зависит от значения параметра record, переданного функции createStream в скрипте публикующего клиента:
- true - поток, опубликованный с использованием этого клиента, будет записан;
- false - поток не будет записан.
Например, в скрипте веб-приложения Stream Recording recording.html, recording.js, содержится следующий код:
Code Block | ||||
---|---|---|---|---|
| ||||
function publishStream(session) {
var streamName = $('#url').val().split('/')[3];
session.createStream({
name: streamName,
display: localVideo,
record: true,
receiveVideo: false,
receiveAudio: false
...
}).publish();
} |
...
Из файла с несколькими потоками внутри по умолчанию может быть воспроизведен только первый поток. Чтобы смотреть все потоки в файле, их необходимо смикшировать. Для этого предназначен инструмент OfflineMP4MixerOfflineMixerTool, запускаемый следующим образом:
...
Пример кадра из микшированного файла
...
Начиная со сборки 5.2.1481, микшируются потоки как из MP4, так и из MKV контейнеров. Результат всегда записывается в MP4 контейнер.
Получение информации о дорожках из записанного файла
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
[ { "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": "pausepause", "startInMs": "0" }, { "endInMs": "50191", "type": "media", "startInMs": "039791" }, { ], "endInMstrackType": "50191VIDEO", "typetrackId": "media2", "startInMswidth": "39791640", "timescale": "90000", } ]"streamName": "test", "trackTypetrackCodec": "VIDEOavc1", "trackIdmediaSessionId": "2ed3ebda0-20ee-11ec-bf06-ef6ec6048b2c", "widthheight": "640360", } ] |
Извлечение отдельных потоков из MKV контейнера
В сборке 5.2.1440 с помощью инструмента для микширования записанных потоков можно извлечь отдельные потоки из MKV контейнера:
Code Block | ||||
---|---|---|---|---|
| ||||
./offline_mixer_tool.sh "timescale": "90000", "streamName": "test", "trackCodec": "avc1", "mediaSessionId": "--pull-streams ../records/multi-recorder___test-record.mkv |
При этом будут созданы MKV файлы для каждого из потоков:
Code Block | ||||
---|---|---|---|---|
| ||||
multi-recorder___test-record_fbbf5b50-20ee-11ec-bf06-ef6ec6048b2c.mkv multi-recorder___test-record_c7bc1460-20ee-11ec-bf06-ef6ec6048b2c.mkv multi-recorder___test-record_ed3ebda0-20ee-11ec-bf06-ef6ec6048b2c", "height": "360" } ] |
Извлечение отдельных потоков из MKV контейнера
В сборке 5.2.1440 с помощью инструмента для микширования записанных потоков можно извлечь отдельные потоки из MKV контейнера:
Code Block | ||||
---|---|---|---|---|
| ||||
./offline_mixer_tool.sh --pull-streams ../records/multi-recorder___test-record.mkv |
...
.mkv |
Если поток был удален из мультирекордера и повторно добавлен, или был добавлен позднее, чем другие потоки, получившиеся паузы по умолчанию будут заполнены, чтобы выровнять извлеченные потоки по времени. При необходимости, заполнение можно отключить
Code Block | ||
---|---|---|
| ||
multi_recorder_mkv_fill_gaps=false |
Скрипт для обработки записанных файлов
По окончании записи нескольких потоков в один файл, запускается cкрипт обработки, заданный настройкой
Code Block | ||
---|---|---|
| ||
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
только результат обработки, чтобы снизить нагрузку на диск во время работы инструмента микширования. При необходимости, можно включить подробное логирование для отладки, установив переменную в скрипте
Code Block | ||||
---|---|---|---|---|
| ||||
multi-recorder___test-record_fbbf5b50-20ee-11ec-bf06-ef6ec6048b2c.mkv
multi-recorder___test-record_c7bc1460-20ee-11ec-bf06-ef6ec6048b2c.mkv
multi-recorder___test-record_ed3ebda0-20ee-11ec-bf06-ef6ec6048b2c.mkv |
Если поток был удален из мультирекордера и повторно добавлен, или был добавлен позднее, чем другие потоки, получившиеся паузы по умолчанию будут заполнены, чтобы выровнять извлеченные потоки по времени. При необходимости, заполнение можно отключить
Code Block | ||
---|---|---|
| ||
multi_recorder_mkv_fill_gaps=false |
Скрипт для обработки записанных файлов
По окончании записи нескольких потоков в один файл, запускается cкрипт обработки, заданный настройкой
Code Block | ||
---|---|---|
| ||
on_multiple_record_hook_script=on_multiple_record_hook.sh |
По умолчанию, скрипт запускает offline_mixer_tool.sh
, передавая ему на вход имя записанного файла.
...
LOGGER_ENABLED=true |
Многопоточное кодирование при микшировании записанных потоков
В сборке 5.2.1089 добавлена возможность включить многопоточное кодирование при микшировании записанных потоков. Для этого в файл /usr/local/FlashphonerWebCallServer/conf/offline_mixer.json
необходимо добавить параметр
Code Block | ||||
---|---|---|---|---|
| ||||
{
...,
"multithreading": true
} |
При использовании многопоточного кодирования записанные потоки микшируются в среднем в два раза быстрее по сравнению с однопоточным.
Количество процессорных потоков при многопоточном кодировании
В сборке 5.2.1523 добавлена настройка количества процессорных потоков, используемых для многопоточного кодирования. По умолчанию, количество процессорных потоков равно половине доступных системе ядер CPU. Например, на сервере с 12 CPU по умолчанию буду использовать 6 потоков
Code Block | ||||
---|---|---|---|---|
| ||||
{
...,
"threadCount": 6
} |
Если микширование записе занимает долгое время, значение можно увеличить, но не рекомедуется указывать больше, чем количество ядер CPU на сервере, которое можно определить при помощи команды
Code Block | ||||
---|---|---|---|---|
| ||||
lscpu | grep -E "^CPU\(s\)" |
Отображение имени записанного потока
По умолчанию, в микшированной записи нескольких потоков отображается имя каждого потока. При необходимости, это можно отключить настройкой в файле /usr/local/FlashphonerWebCallServer/logs/multi-record.log
только результат обработки, чтобы снизить нагрузку на диск во время работы инструмента микширования. При необходимости, можно включить подробное логирование для отладки, установив переменную в скриптеconf/offline_mixer.json
Code Block | ||||
---|---|---|---|---|
| ||||
{
...,
"mixerDisplayStreamName": false
} |
При записи потоков в конференции с использованием RoomApi, имя потока включает имя комнаты конференции и идентификатор потока участника, например room-1882a6-bob-037c
. В сборке 5.2.1642 добавлена возможность исключить имя комнаты при помощи настроек
Code Block | ||||
---|---|---|---|---|
| ||||
LOGGER_ENABLED=true |
...
| ||
{
...,
"mixerDisplayStreamName": true,
"mixerTextDisplayRoom": false,
"labelReplaceRegex": "\\w+-\\w+-([^\\-]+)-\\w+",
"labelReplaceWith":""
} |
Здесь:
- labelReplaceRegex - регулярное выражение для замены элементов в имени потока
- labelReplaceWith - строка, которая должна заменить элементы, найденные по регулярному выражению, пустая строка исключает найденные элементы
В этом случае для указанного выше примера будет отображаться только имя участника bob.
Декодирование символов в имени записанного потока
В сборке 5.2.10891751 добавлена возможность включить многопоточное кодирование при микшировании записанных потоков. Для этого в файл /usr/local/FlashphonerWebCallServer/conf/offline_mixer.json
необходимо добавить параметрдекодирования символов в имени потока, закодированных на стороне клиента при помощи encodeURIComponent()
Code Block | ||||
---|---|---|---|---|
| ||||
{ ..., "multithreadingmixerDecodeStreamName": true } |
При использовании многопоточного кодирования записанные потоки микшируются в среднем в два раза быстрее по сравнению с однопоточнымВ этом случае в изображении будут отображаться декодированные символы, если такие символы есть в используемом шрифте, или близкие к ним по начертанию.
Отправка данных о завершении записи нескольких потоков
...