How to publish with WebRTC using H264

This has been asked many times on how to get WebRTC to publish with H264 using the WebRTC publisher provided by Wowza. This code is extremely basic but by default publishes VP8. There are two ways to resolve this problem and we are going to choose one that requires no changes to the Wowza configuration/session interface.

If you look at section

function gotDescription(description)
    console.log('gotDescription: '+JSON.stringify({'sdp': description}));
    peerConnection.setLocalDescription(description, function () {

        sendPost(postURL, '{"direction":"publish", "command":"sendOffer", "streamInfo":'+JSON.stringify(streamInfo)+', "sdp":'+JSON.stringify(description)+'}');

    }, function() {console.log('set description error')});

This is where we have the SDP information to publish a stream and is added to the local session with the peerConnection.setLocalDescription call. This presents an opportunity to change the SDP data.

If you look through the SDP data, it is conveniently logged to the console in your browser, then you can see where the video codec is set, so VP8.

To change this data all we need to do is a search and replace for VP8 to H264. Although not strictly the best way and certainly additional changes could be made, it does appear to work.

To do this add this function

function flipVideoCodec(description) {
	description.sdp = description.sdp.replace(/VP8/g, "H264");
    return description;

To the end of the webrtc.js file and then add

description = flipVideoCodec(description);

after the console.log entry, so resulting in the function now looking like this

function gotDescription(description)
    console.log('gotDescription: '+JSON.stringify({'sdp': description}));
    description = flipVideoCodec(description);
    peerConnection.setLocalDescription(description, function () {

        sendPost(postURL, '{"direction":"publish", "command":"sendOffer", "streamInfo":'+JSON.stringify(streamInfo)+', "sdp":'+JSON.stringify(description)+'}');

    }, function() {console.log('set description error')});

Now when you publish to Wowza Streaming Engine you should see H264 as the video codec as follows

INFO server comment - onRTPSessionCreate[com.wowza.wms.rtp.model.RTPSession@46157da1]: clientId:1030441568
INFO server comment - onStreamCreate[]: clientId:-1
INFO stream create - -
INFO server comment - WebRTCCommands.sendOffer: audioCodec:opus
INFO server comment - WebRTCRTPHandler.bind: port:1
INFO server comment - WebRTCRTPHandler.bind: port:2
INFO server comment - WebRTCCommands.sendOffer: videoCodec:H264
INFO server comment - WebRTCRTPHandler.bind: port:3
INFO server comment - WebRTCRTPHandler.bind: port:4
INFO server comment - WebRTCCommands.sendOffer: iceCandidate:candidate:0 1 UDP 50 6970 typ host generation 0
INFO server comment - Starting runner thread
INFO server comment - Handshake complete
INFO stream publish myStream -
onPublish[live/_definst_/myStream]: isRecord:false isAppend:false
INFO server comment - RTCPHandler.sendFirstRTCPRR[3016964302,4,/]
INFO server comment - RTCPHandler.sendFirstRTCPRR[1986185923,2,/]
INFO server comment - LiveStreamPacketizerCupertino.init[live/_definst_/myStream]: chunkDurationTarget: 10000
INFO server comment - LiveStreamPacketizerCupertino.init[live/_definst_/myStream]: audioGroupCount: 3
INFO server comment - LiveStreamPacketizerCupertino.init[live/_definst_/myStream]: playlistChunkCount:3
INFO server comment - MediaStreamMap.getLiveStreamPacketizer[live/_definst_/myStream]: Create live stream packetizer: cupertinostre
INFO server comment - CupertinoPacketHandler.startStream[live/_definst_/myStream]
INFO server comment - LiveStreamPacketizerCupertino.handlePacket[live/_definst_/myStream]: Video codec:H264 isCompatible:true
INFO server comment - LiveStreamPacketizerCupertino.handlePacket[live/_definst_/myStream]: Audio codec:OPUS isCompatible:false
INFO server comment - LiveStreamPacketizerCupertino.handlePacket[live/_definst_/myStream][avc1.66.31]: H.264 Video info: {H264Codec
ConfigInfo: codec:H264, profile:Baseline, level:3.1, frameSize:640x480, displaySize:640x480}
WARN server comment - CupertinoPacketHandler.handleHolder[live/_definst_/myStream]: Invalid video/audio codec combination for iPhon
e/iPod: video:H264 audio:OPUS
WARN server comment - CupertinoPacketHandler.handleHolder[live/_definst_/myStream]: Invalid audio codec for iPhone/iPod:OPUS
INFO server comment - LiveStreamPacketizerCupertino.endChunkTS[live/_definst_/myStream]: Add chunk: id:1 mode:TS[H264,OPUS] a/v/k:0
/32/1 duration:1334

Please be aware this does not work on all browsers and all OSs. WebRTC is still maturing and consequently is not consistent across different vendors. This has been tested on Chrome using Windows 10 and nothing else.

You can download a complete webrtc.js here but do note you will need to change the SSL hostname for your deployment.

Comments are closed.