WebRTC as RTMP re-publishing - Failed by RTMP writer error

mit

New Member
взял код из примера, пытаюсь создать стрим в ютубе, через 2 мин после старта падает с ошибкой, стрим до ютуба так и не дошел

  1. {message: "notifyStreamStatusEvent", data: [{,…}]}
    1. data: [{,…}]
      1. 0: {,…}
        1. audioBitrate: 0
        2. audioCodec: "opus"
        3. audioState: {muted: false}
        4. bitrate: 0
        5. codecImpl: ""
        6. createDate: 1619037892447
        7. cvoExtension: false
        8. fps: 0
        9. gop: 0
        10. hasAudio: true
        11. hasVideo: true
        12. height: 240
        13. history: false
        14. info: "Failed by RTMP writer error"
        15. lastStatus: "FAILED"
        16. logger: {name: "Stream", debugEnabled: false, infoEnabled: true, warnEnabled: true, errorEnabled: true,…}
        17. maxBitrate: 0
        18. mediaProvider: "WebRTC"
        19. mediaSessionId: "6ad8xxxxxxxxxxxxxxxab6fb"
        20. mediaType: "publish"
        21. minBitrate: 0
        22. name: "f1r5-xxxxxx-9h03"
        23. namedParams: {}
        24. protocols: ["ws", "wss", "vod", "vod-live", "rtmp", "rtsp", "pcap"]
        25. published: true
        26. quality: 0
        27. record: false
        28. rtmpUrl: "rtmp://a.rtmp.youtube.com/live2"
        29. status: "FAILED"
        30. streamInfo: {nodeId: null, appKey: null, sessionId: null, mediaSessionId: "6ad8bdf0-a2xxxxxxxxxx50ab6fb",…}
        31. transport: "UDP"
        32. videoCodec: "H264"
        33. videoState: {muted: false}
        34. width: 320
    2. message: "notifyStreamStatusEvent"
 

Max

Administrator
Staff member
Проверили Ваши логи.
Рекомендуем обновить JDK до 12 или 14, как описано здесь, поскольку в JDK 8 и JDK 11 есть проблема, приводящая к повышенной нагрузке CPU при простое сервера (когда на сервер нет публикаций). Отметим также, что конфигурация сервера, которую ВЫ используете, пригода для тестирования, но не для нагрузочного тестирования и не для продакшна.
Републикация WebRTC как RTMP на Youtube не работает у Вас по следующим причинам:
1. Для публикации на Youtube необходимо активировать настройку сервера
Code:
rtmp_flash_ver_subscriber=LNX 76.219.189.0
которая у Вас закомментирована
2. Если Вы используете пример WebRTC as RTMP c настройкой сервера
Code:
rtmp_transponder_full_url=true
необходимо в поле RTMP URL указать полный URL для републикации, включая stream key
Code:
rtmp://a.rtmp.youtube.com/live2/f1r5-****-****-****-****[CODE]
Имя потока для публикации на WCS в поле [ICODE]Stream[/ICODE] при этом может быть любым, например, test.
 

mit

New Member
спасибо, ютуб и вк получилось запустить, а как быть с ФБ и их rtmps://live-api-s.facebook.com:443/rtmp/ ? пока также с ошибкой вылетает

и дайте плз пример как запустить один входящий webrtc одновременно на несколько rtmp
 

Max

Administrator
Staff member
спасибо, ютуб и вк получилось запустить, а как быть с ФБ и их rtmps://live-api-s.facebook.com:443/rtmp/ ? пока также с ошибкой вылетает
На FB должно работать с теми же настройками, что и на Youtube. Возможно, необходима настройка
Code:
rtmp_transponder_send_metadata=true
и дайте плз пример как запустить один входящий webrtc одновременно на несколько rtmp
В этом случае нужно опубликовать поток на WCS по WebRTC, например, из примера Two Way Streaming, и запустить нужные RTMP ретрансляции по REST API
Code:
POST /rest-api/push/startup HTTP/1.1
Host: wcs:8081
Content-Type: application/json
 
{
    "streamName": "test",
    "rtmpUrl":"rtmps://live-api-s.facebook.com:443/rtmp/very-long-fb-stream-key"
    "rtmpTransponderFullUrl": true
    "rtmpFlashVersion":"LNX 76.219.189.0"
}
 

mit

New Member
вот я сделал, как понял:

JavaScript:
function startStreaming(session) {
    session.createStream({
        name: "f1r5-xxxxxx-9h03",
        rtmpUrl: "rtmp://b.rtmp.youtube.com/live2?backup=1",
        display: localVideo,
    }).on(Flashphoner.constants.STREAM_STATUS.PUBLISHING, function (publishStream) {
        setStatus(Flashphoner.constants.STREAM_STATUS.PUBLISHING);

        $.ajax({
            type: 'post',
            url: `https://xxxxxxxxx:8444/rest-api/push/find_all`,
            success: function (res) {
                console.log(res);
            },
        });

        $.ajax({
            type: 'post',
            url: `https://xxxxxxxx:8444/rest-api/push/startup`,
            data: JSON.stringify({
                "streamName": "xxxxxxxxxxxxxxxxxxx",
                "rtmpUrl": "rtmp://ovsu.mycdn.me/input/"
            }),
            success: function (res) {
                console.log(res);
            },
        });

    }).on(Flashphoner.constants.STREAM_STATUS.UNPUBLISHED, function () {
        setStatus(Flashphoner.constants.STREAM_STATUS.UNPUBLISHED);
    }).on(Flashphoner.constants.STREAM_STATUS.FAILED, function () {
        setStatus(Flashphoner.constants.STREAM_STATUS.FAILED);
    }).publish();
}
на рест запросы получаю 404
  1. error: "Not Found"
  2. exception: "com.flashphoner.rest.server.exception.NotFoundException"
  3. message: "Not found any transponder"
  4. path: "/rest-api/push/find_all"
  5. status: 404
  6. timestamp: 1619200650128

  1. error: "Not Found"
  2. exception: "com.flashphoner.rest.server.exception.NotFoundException"
  3. message: "Can not start transponder"
  4. path: "/rest-api/push/startup"
  5. status: 404
  6. timestamp: 1619200650139
 

mit

New Member
если указать у рест запроса тотже streamName, что и у созданного, то тогда 200 ответ, но у них же разные должны быть
 

mit

New Member
вот так в итоге получилось

JavaScript:
function startStreaming(session) {
    let streamName = '12938747891';
    session.createStream({
        name: streamName,
        display: localVideo,

    }).on(Flashphoner.constants.STREAM_STATUS.PUBLISHING, function (publishStream) {
        setStatus(Flashphoner.constants.STREAM_STATUS.PUBLISHING);

        $.ajax({
            type: 'post',
            contentType: 'application/json',
            url: `https://sxxxxx:8444/rest-api/push/startup`,
            data: JSON.stringify({
                "streamName": streamName,
                "rtmpUrl": "rtmp://a.rtmp.youtube.com/live2/fxxxxxxxxxxxx3",
                "rtmpTransponderFullUrl": true,
            }),
            success: function (res) {
                console.log(res);
            },
        });

        $.ajax({
            type: 'post',
            contentType: 'application/json',
            url: `https://sxxxxxx:8444/rest-api/push/startup`,
            data: JSON.stringify({
                "streamName": streamName,
                "rtmpUrl": "rtmp://ovsu.mycdn.me/input/2xxxxdq2lge",
                "rtmpTransponderFullUrl": true,
            }),
            success: function (res) {
                console.log(res);
            },
        });
 
Last edited:

Max

Administrator
Staff member
Вариант 1

Есть две фазы:

1. Публикация стрима из браузера.

В этом случае rtmpUrl передавать не нужно.

Code:
session.createStream({
        name: streamName,
        display: localVideo,
}).publish();

2. Републикация этого стрима по RTMP по REST API через /push/startup без изменения имени.

Вариант 2

Эти две фазы можно совместить, передав параметр rtmpUrl, в этом случае REST запрос не требуется

Code:
session.createStream({
        name: "f1r5-xxxxxx-9h03",
        display: localVideo,
        rtmpUrl: "rtmp://a.rtmp.youtube.com/live2"
}).publish();
Имя потока передаем в точности, как указано на youtube, чтобы построился полный урл rtmp://a.rtmp.youtube.com/live2/f1r5-xxxxxx-9h03

Вариант 3 (который у вас заработал)

В некоторых случаях, например при рестриминге на Youtube и Facebook одного и того же потока, требуется задать два разных урла. Тогда используется "rtmpTransponderFullUrl": true, который говорит использовать для републикации указанный урл полностью и игнорировать имя стрима streamName.
 

mit

New Member
Max, новая проблема.

создаю стрим в ютубе через запрос к апи:

$data = [
'snippet' => [
'title' => 'Your new video stream\'s name',
'description' => 'A description of your video stream. This field is optional.',
],
'cdn' => [
'frameRate' => '60fps',
'ingestionType' => 'rtmp',
'resolution' => '1080p',
],
'contentDetails' => [
'isReusable' => true,
],
];

$res = $adapter->apiRequest('https://youtube.googleapis.com/youtube/v3/liveStreams?part=snippet,cdn,contentDetails,status',
"POST", $data,
["Content-Type" => "application/json"],
true);

получаю такой ответ:

stdClass Object
(
[kind] => youtube#liveStream
[etag] => xxxxxx
[id] => xxxxxxxxxxx
[snippet] => stdClass Object
(
[publishedAt] => 2021-05-11T20:43:42Z
[channelId] => xxxxxxxxx
[title] => Your new video stream's name
[description] => A description of your video stream. This field is optional.
[isDefaultStream] =>
)

[cdn] => stdClass Object
(
[ingestionType] => rtmp
[ingestionInfo] => stdClass Object
(
[streamName] => g1c6-xxxxxxxxxxxxxxxxx-2aqv
[ingestionAddress] => rtmp://a.rtmp.youtube.com/live2
[backupIngestionAddress] => rtmp://b.rtmp.youtube.com/live2?backup=1
[rtmpsIngestionAddress] => rtmps://a.rtmps.youtube.com/live2
[rtmpsBackupIngestionAddress] => rtmps://b.rtmps.youtube.com/live2?backup=1
)

[resolution] => 1080p
[frameRate] => 60fps
)

[status] => stdClass Object
(
[streamStatus] => ready
[healthStatus] => stdClass Object
(
[status] => noData
)

)

[contentDetails] => stdClass Object
(
[closedCaptionsIngestionUrl] => http://upload.youtube.com/closedcaption?cid=g1c6-xxxxxxxxxxxxx-2aqv
[isReusable] => 1
)

)

если запустить стрим на тот поток, который создан вручную в студии ютуба, все ок, трансляция идет
если запустить стрим на поток, полученный по апи, трансляция не доходит до ютуба, куда копать? какие логи? какие средства отладки?
 

Max

Administrator
Staff member
если запустить стрим на тот поток, который создан вручную в студии ютуба, все ок, трансляция идет
если запустить стрим на поток, полученный по апи, трансляция не доходит до ютуба, куда копать? какие логи? какие средства отладки?
Прежде всего, необходимо проверить, что публикация на полученный по API RTMP URL работает из ffmpeg.
Если публикация из ffmpeg работает, необходимо проверить серверные логи /usr/local/FlashphonerWebCallServer/logs/server_logs/flashphoner.log, туда выводятся команды RTMP протокола и видно, установилось ли RTMP соединение. Также необходимо собрать дамп трафика на порту 1935, в дампе будет видно последовательность команд RTMP и пакеты медиаданных, либо то, на каком этапе завершилась установка соединения в случае ошибки.
Логи соберите по этой инструкции, сбор дампа необходимо стартовать до попытки публикации на Youtube. Архивы вышлите, используя эту форму
 
Top