...
В сборке 5.2.1012 добавлена возможность записи нескольких потоков в один файл. В дальнейшем потоки могут быть извлечены из этого файла и смикшированы специальным инструментом. Несколько потоков могут быть записаны только в MP4 контейнер (H264 + AAC)контейнер или, начиная со сборки 5.2.1440, в MKV контейнер. Эта возможность предназначена, например, для записи видеоконференций. В отличие от MCU микшера, здесь микширование работает только при обработке уже записанного файла, и позволяет расходовать меньше ресурсов процессора непосредственно во время проведения конференции.
Запись нескольких потоков управляется по REST API.
Поддерживаемые кодеки
Контейнер MP4:
- H264
- AAC
Контейнер MKV:
- H264
- VP8
- Opus
- AAC
- PCMA
- PCMU
- G722
REST API для мультирекордера
REST-запрос должен быть HTTP/HTTPS POST запросом в таком виде:
...
- streaming.flashphoner.com - адрес WCS-сервера
- 8081 - стандартный REST / HTTP порт WCS-сервера
- 8444 - стандартный HTTPS порт
- rest-api - обязательный префикс
- /multipleRecorder/startup - используемый REST-вызов
REST-методы и статусы ответа
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 рекордера, с заменой символов, не допустимых к использованию в именах файлов, на подчеркивания.
...
Выбор контейнера для записи
Данная возможность доступна, начиная со сборки 5.2.1440. По умолчанию, запись производится в контейнер MP4
Code Block | ||
---|---|---|
| ||
multi_recorder_type=MP4 |
При необходимости (например, при публикации VP8+Opus потоков в конференции), можно выбрать контейнер MKV
Code Block | ||
---|---|---|
| ||
multi_recorder_type=MKV |
Имя записываемого файла
Имя файла для записи нескольких потоков формируется по шаблону. При этом:
1. Параметр {streamName} подставляется согласно URI рекордера, с заменой символов, не допустимых к использованию в именах файлов, на подчеркивания.
2. Параметры {startTime}, {endTime} не могут быть определены, поскольку зависят от меток времени в потоке, а потоков в данном случае несколько. Поэтому рекомендуется для присвоения метки времени файлу использовать параметры {startTimeMillis}, {endTimeMillis}, которые проставляются согласно часам сервера.
...
Пример кадра из микшированного файла
...
Warning |
---|
Микширование работает только для контейнера 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": "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крипт обработки, заданный настройкой
Извлечение отдельных потоков из MKV контейнера
В сборке 5.2.1440 с помощью инструмента для микширования записанных потоков можно извлечь отдельные потоки из MKV контейнера:
Code Block | ||||
---|---|---|---|---|
| ||||
on_multiple_record_hook_script=on_multiple_record_hook.sh |
...
./offline_mixer_tool.sh |
...
--pull-streams ../records/multi-recorder___test-record.mkv |
При этом будут созданы MKV файлы для каждого из потоков:
Code Block | ||||
---|---|---|---|---|
| ||||
LOGGER_ENABLED=true |
Многопоточное кодирование при микшировании записанных потоков
В сборке 5.2.1089 добавлена возможность включить многопоточное кодирование при микшировании записанных потоков. Для этого в файл /usr/local/FlashphonerWebCallServer/conf/offline_mixer.json
необходимо добавить параметр
Code Block | ||||
---|---|---|---|---|
| ||||
{
...,
"multithreading": true
} |
При использовании многопоточного кодирования записанные потоки микшируются в среднем в два раза быстрее по сравнению с однопоточным.
Отправка данных о завершении записи нескольких потоков
В сборке 5.2.1123 добавлена возможность отправки POST запроса на указанный URL при завершении записи нескольких потоков в файл и микширования этой записи. Таким образом, можно получить информацию о том, в какой файл смикшированы записанные потоки из чат-комнаты.
URL для отправки запроса задается в файле /usr/local/FlashphonerWebCallServer/conf/offline_mixer.json
:
Code Block | ||||
---|---|---|---|---|
| ||||
{
...,
"callbackUrl": "http://backend.url/multiRecorderCallback"
} |
...
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
. Поэтому при установке сборки , передавая ему на вход имя записанного файла.
Начиная со сборки 5.2.1123 поверх предыдущей, или в том случае, если используется собственный скрипт 1023, скрипт on_multiple_record_hook.sh
по умолчанию записывает в лог /usr/local/FlashphonerWebCallServer/logs/multi-record.log
, необходимо модифицировать его следующим образом:только результат обработки, чтобы снизить нагрузку на диск во время работы инструмента микширования. При необходимости, можно включить подробное логирование для отладки, установив переменную в скрипте
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
# This script copies a recorded stream to client/records FILE_NAME=$1 CREATION_MODIFICATION_TIME=$2 DURATION_IN_MS=$3 RECORDER_URI=$4 WCS_HOME=LOGGER_ENABLED=true |
Многопоточное кодирование при микшировании записанных потоков
В сборке 5.2.1089 добавлена возможность включить многопоточное кодирование при микшировании записанных потоков. Для этого в файл /usr/local/FlashphonerWebCallServer
...
/conf/offline_mixer
...
.json
необходимо добавить параметр
Code Block | ||||
---|---|---|---|---|
| ||||
{
...,
"multithreading": true
} |
При использовании многопоточного кодирования записанные потоки микшируются в среднем в два раза быстрее по сравнению с однопоточным.
Отправка данных о завершении записи нескольких потоков
В сборке 5.2.1123 добавлена возможность отправки POST запроса на указанный URL при завершении записи нескольких потоков в файл и микширования этой записи. Таким образом, можно получить информацию о том, в какой файл смикшированы записанные потоки из чат-комнаты.
URL для отправки запроса задается в файле /usr/local/FlashphonerWebCallServer/conf/offline_mixer.json
:
Code Block | ||||
---|---|---|---|---|
| ||||
{
...,
"callbackUrl": "http://backend.url/multiRecorderCallback"
} |
Данные для отправки передаются через скрипт /usr/local/FlashphonerWebCallServer/bin/on_multiple_record_hook.sh
при вызове offline_mixer_tool.sh
. Поэтому при установке сборки 5.2.1123 поверх предыдущей, или в том случае, если используется собственный скрипт on_multiple_record_hook.sh
, необходимо модифицировать его следующим образом:
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
# This script copies a recorded stream to client/records
FILE_NAME=$1
CREATION_MODIFICATION_TIME=$2
DURATION_IN_MS=$3
RECORDER_URI=$4
WCS_HOME=/usr/local/FlashphonerWebCallServer
LOG_FILE=$WCS_HOME/logs/multi-record.log
MIXER_TOOL=$WCS_HOME/tools/offline_mixer_tool.sh
# Set LOGGER_ENABLED to true to enable mixing debug logging
LOGGER_ENABLED=false
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Start mixing multiple recording file $FILE_NAME" >> $LOG_FILE
if $LOGGER_ENABLED; then
bash $MIXER_TOOL $FILE_NAME $CREATION_MODIFICATION_TIME $DURATION_IN_MS $RECORDER_URI >> $LOG_FILE 2>&1
else
bash $MIXER_TOOL $FILE_NAME $CREATION_MODIFICATION_TIME $DURATION_IN_MS $RECORDER_URI > /dev/null 2>&1
fi
CODE=$?
if [ "$CODE" -ne "0" ]; then
if [ "$CODE" -eq "64" ]; then
echo "ERROR: File to mix not found" >> $LOG_FILE
elif [ "$CODE" -eq "65" ]; then
echo "ERROR: Offline mixer config not found" >> $LOG_FILE
else
echo "ERROR: Offline mixer tool error code: $CODE" >> $LOG_FILE
fi
exit $CODE
fi
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Multiple recording file $FILE_NAME is mixed successfully" >> $LOG_FILE
exit 0 |
...
Code Block | ||
---|---|---|
| ||
v=0 o=- 1988962254 1988962254 IN IP4 0.0.0.0 c=IN IP4 0.0.0.0 t=0 0 a=sdplang:en m=audio 0 RTP/AVP 97 8 0 102 103 104 105 106 107 108 109 110 a=rtpmap:97 SPEEX/16000 a=rtpmap:8 PCMA/8000 a=rtpmap:0 102 103 104 105 106 107 108 109 110 PCMU/8000 a=rtpmap:102 mpeg4-generic/48000/1 a=rtpmap:103 mpeg4-generic/44100/1 a=rtpmap:104 mpeg4-generic/32000/1 a=rtpmap:105 mpeg4-generic/24000/1 a=rtpmap:106 mpeg4-generic/22050/1 a=rtpmap:97107 SPEEXmpeg4-generic/16000/1 a=rtpmap:8 PCMA/8000108 mpeg4-generic/12000/1 a=rtpmap:0 PCMU/8000109 mpeg4-generic/11025/1 a=rtpmap:102110 mpeg4-generic/48000/1 a=rtpmap:103 mpeg4-generic/44100/1 a=rtpmap:104 mpeg4-generic/32000/1 a=rtpmap:105 mpeg4-generic/24000/1 a=rtpmap:106 mpeg4-generic/22050/1 a=rtpmap:107 mpeg4-generic/16000/1 a=rtpmap:108 mpeg4-generic/12000/1 a=rtpmap:109 mpeg4-generic/11025/1 a=rtpmap:110 mpeg4-generic/8000/1 a=sendonly |
11. Запись потока начинается только после получения хотя бы одного ключевого кадра
Симптомы: при старте записи (например, по REST API) файл не создается, ошибок в серверном логе при этом нет, и поток играет в браузере (до переподключения зрителя)
Решение: обеспечить периодическую отсылку ключевых кадров для WebRTC публикаций при помощи настройки
Code Block | ||
---|---|---|
| ||
periodic_fir_request=true |
для RTMP публикаций соответствующими настройками кодировщика
...
8000/1
a=sendonly |
11. Запись потока начинается только после получения хотя бы одного ключевого кадра
Симптомы: при старте записи (например, по REST API) файл не создается, ошибок в серверном логе при этом нет, и поток играет в браузере (до переподключения зрителя)
Решение: обеспечить периодическую отсылку ключевых кадров для WebRTC публикаций при помощи настройки
Code Block | ||
---|---|---|
| ||
periodic_fir_request=true |
для RTMP публикаций соответствующими настройками кодировщика
12. При воспроизведении потока, извлеченного из записи мультирекордера в формате MKV, проигрыватель проскакивает паузы в потоке
Симптомы: при проигрывании извлеченного потока в VLC, пауза в потоке пропускается
Решение: использовать настройку
Code Block | ||
---|---|---|
| ||
multi_recorder_mkv_fill_gaps=true |
13. Если WebRTC поток записывается одновременно в отдельный файл MKV и в мультирекордер MKV, рекомендуется обеспечить регулярное поступление ключевых фреймов
Симптомы: при проигрывании отдельного файла MKV VLC перескакивает на время добавление этого потока в мультирекордер
Решение: обеспечить периодическую отсылку ключевых кадров для WebRTC публикаций при помощи настройки
Code Block | ||
---|---|---|
| ||
periodic_fir_request=true |
14. При извлечении из файла мультирекордера в контейнере MKV потока с аудио G722 могут наблюдаться кратковременные искажения аудио
Симптомы: при проигрывании извлеченного файла с аудио G722, если поток был удален и снова добавлен в мультирекордер, слышны кратковременные искажения звука при добавлении потока
Решение: использовать аудиокодек Opus
15. При извлечении из файла мультирекордера в контейнере MKV потока с аудио PCMA после удаления потока из мультирекордера аудио завершается раньше, чем видео
Симптомы: при проигрывании извлеченного файла с аудио PCMA, если поток был удален из мультирекордера, аудио завершается раньше, чем видео
Решение: использовать аудиокодек Opus