Skip to content

Commit

Permalink
Implemented full RTMP and external URL services
Browse files Browse the repository at this point in the history
  • Loading branch information
jalamprea committed Oct 17, 2019
1 parent b295e6a commit ede1c36
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 92 deletions.
4 changes: 0 additions & 4 deletions public/css/wp-agora-io-public.css
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,6 @@ body .agora {
margin: 0 0 5px 0;
}

#add-rtmp-btn {
padding: 0.5rem 1.15rem;
}

.remote-stream-container {
display: inline-block;
}
Expand Down
81 changes: 24 additions & 57 deletions public/js/agora-broadcast-client.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/**
* Agora Broadcast Client
*/

const RADIX_DECIMAL = 10;
const RADIX_HEX = 16;
// stream references (keep track of active streams)
var remoteStreams = {}; // remote streams obj struct [id : stream]

Expand Down Expand Up @@ -170,77 +171,43 @@ function getMicDevices() {
}

function startLiveTranscoding() {
AgoraRTC.Logger.info("start live transcoding");
var rtmpUrl = jQuery('#rtmp-url').val();
var width = parseInt(jQuery('#window-scale-width').val(), 10);
var height = parseInt(jQuery('#window-scale-height').val(), 10);

var configRtmp = {
width: width,
height: height,
videoBitrate: parseInt(jQuery('#video-bitrate').val(), 10),
videoFramerate: parseInt(jQuery('#framerate').val(), 10),
lowLatency: (jQuery('#low-latancy').val() === 'true'),
audioSampleRate: parseInt(jQuery('#audio-sample-rate').val(), 10),
audioBitrate: parseInt(jQuery('#audio-bitrate').val(), 10),
audioChannels: parseInt(jQuery('#audio-channels').val(), 10),
videoGop: parseInt(jQuery('#video-gop').val(), 10),
videoCodecProfile: parseInt(jQuery('#video-codec-profile').val(), 10),
userCount: 1,
userConfigExtraInfo: {},
backgroundColor: parseInt(jQuery('#background-color-picker').val(), 16),
transcodingUsers: [{
uid: window.localStreams.uid,
alpha: 1,
width: width,
height: height,
x: 0,
y: 0,
zOrder: 0
}],
};
AgoraRTC.Logger.info("Start live transcoding...");
var rtmpURL = jQuery('#input_rtmp_url').val();
var rtmpKey = jQuery('#input_private_key').val();
var width = parseInt(jQuery('#window-scale-width').val(), RADIX_DECIMAL);
var height = parseInt(jQuery('#window-scale-height').val(), RADIX_DECIMAL);

// set live transcoding config
window.agoraClient.setLiveTranscoding(configRtmp);
if(rtmpUrl !== '') {
window.agoraClient.startLiveStreaming(rtmpUrl, true)
window.externalBroadcastUrl = rtmpUrl;
addExternalTransmitionMiniView(rtmpUrl)
window.agoraClient.setLiveTranscoding(window.defaultConfigRTMP);

if(rtmpURL.length>0 && rtmpKey.length>0) {
const sep = rtmpURL.lastIndexOf('/')===rtmpURL.length-1 ? '' : '/';
window.externalBroadcastUrl = rtmpURL + sep + rtmpKey;
console.log(window.externalBroadcastUrl);
window.agoraClient.startLiveStreaming(window.externalBroadcastUrl, true)
addExternalTransmitionMiniView(window.externalBroadcastUrl)
}
}

function addExternalSource() {
var externalUrl = jQuery('#external-url').val();
var width = parseInt(jQuery('#external-window-scale-width').val(), 10);
var height = parseInt(jQuery('#external-window-scale-height').val(), 10);

var injectStreamConfig = {
width: width,
height: height,
videoBitrate: parseInt(jQuery('#external-video-bitrate').val(), 10),
videoFramerate: parseInt(jQuery('#external-framerate').val(), 10),
audioSampleRate: parseInt(jQuery('#external-audio-sample-rate').val(), 10),
audioBitrate: parseInt(jQuery('#external-audio-bitrate').val(), 10),
audioChannels: parseInt(jQuery('#external-audio-channels').val(), 10),
videoGop: parseInt(jQuery('#external-video-gop').val(), 10)
};

var externalUrl = jQuery('#input_external_url').val();

// set live transcoding config
window.agoraClient.addInjectStreamUrl(externalUrl, injectStreamConfig)
injectedStreamURL = externalUrl;
window.agoraClient.addInjectStreamUrl(externalUrl, window.injectStreamConfig)
window.injectedStreamURL = externalUrl;
// TODO: ADD view for external url (similar to rtmp url)
}

// RTMP Connection (UI Component)
function addExternalTransmitionMiniView(rtmpUrl) {
function addExternalTransmitionMiniView(rtmpURL) {
var container = jQuery('#rtmp-controlers');
// append the remote stream template to #remote-streams
container.append(
jQuery('<div/>', {'id': 'rtmp-container', 'class': 'container row justify-content-end mb-2'}).append(
jQuery('<div/>', {'class': 'pulse-container'}).append(
jQuery('<button/>', {'id': 'rtmp-toggle', 'class': 'btn btn-lg col-flex pulse-button pulse-anim mt-2'})
),
jQuery('<input/>', {'id': 'rtmp-url', 'val': rtmpUrl, 'class': 'form-control col-flex" value="rtmps://live.facebook.com', 'type': 'text', 'disabled': true}),
jQuery('<input/>', {'id': 'rtmp-url', 'val': rtmpURL, 'class': 'form-control col-flex" value="rtmps://live.facebook.com', 'type': 'text', 'disabled': true}),
jQuery('<button/>', {'id': 'removeRtmpUrl', 'class': 'btn btn-lg col-flex close-btn'}).append(
jQuery('<i/>', {'class': 'fas fa-xs fa-trash'})
)
Expand All @@ -249,7 +216,7 @@ function addExternalTransmitionMiniView(rtmpUrl) {

jQuery('#rtmp-toggle').click(function() {
if (jQuery(this).hasClass('pulse-anim')) {
window.agoraClient.stopLiveStreaming(externalBroadcastUrl)
window.agoraClient.stopLiveStreaming(window.externalBroadcastUrl)
} else {
window.agoraClient.startLiveStreaming(externalBroadcastUrl, true)
}
Expand All @@ -258,8 +225,8 @@ function addExternalTransmitionMiniView(rtmpUrl) {
});

jQuery('#removeRtmpUrl').click(function() {
window.agoraClient.stopLiveStreaming(externalBroadcastUrl);
externalBroadcastUrl = '';
window.agoraClient.stopLiveStreaming(window.externalBroadcastUrl);
window.externalBroadcastUrl = '';
jQuery('#rtmp-container').remove();
});

Expand Down
30 changes: 24 additions & 6 deletions public/js/broadcast-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,30 @@ function enableUiControls() {
});

jQuery("#start-RTMP-broadcast").click(function(){
var formValid = document.getElementById('rtmp-config').checkValidity();
var errorEl = jQuery('#rtmp-error-msg');
if (!formValid) {
errorEl.show();
return;
} else {
errorEl.hide();
}

startLiveTranscoding();
jQuery('#addRtmpConfigModal').modal('toggle');
jQuery('#rtmp-url').val('');
// jQuery('#input_rtmp_url').val('');
});

jQuery("#add-external-stream").click(function(){
jQuery("#add-external-stream").click(function(){
var formValid = document.getElementById('external-inject-config').checkValidity();
var errorEl = jQuery('#external-url-error');
if (!formValid) {
errorEl.show();
return;
} else {
errorEl.hide();
}
//
addExternalSource();
jQuery('#add-external-source-modal').modal('toggle');
});
Expand Down Expand Up @@ -220,14 +238,14 @@ function startVideoRecording(cb) {
window.uid = res.uid;

setTimeout(function() {
window.resourceId = null;
}, 1000*60*4); // Agora DOCS: The resource ID is valid for five minutes.
// window.resourceId = null;
}, 1000*60*5); // Agora DOCS: The resource ID is valid for five minutes.
cb(null, res);
} else {
cb(res, null);
}
}).fail(function(err) {
console.error('API Error:',err);
console.error('API Error:', err.responseJSON.errors);
cb(err, null);
})
}
Expand All @@ -250,7 +268,7 @@ function stopVideoRecording(cb) {
cb(null, res);

}).fail(function(err) {
console.error('API Error:',err);
console.error('API Error:', err.responseJSON.errors);
cb(err, null);
})
}
Expand Down
85 changes: 60 additions & 25 deletions public/views/wp-agora-io-broadcast.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@

<div id="lower-ui-bar" class="row mb-1">
<div id="rtmp-btn-container" class="col ml-3 mb-2">
<button id="rtmp-config-btn" type="button" class="btn btn-primary btn-md rtmp-btn" data-toggle="modal" data-target="#addRtmpConfigModal">
<button id="rtmp-config-btn" type="button" class="btn btn-primary btn-md rtmp-btn"
data-toggle="modal" data-target="#addRtmpConfigModal">
<i id="rtmp-config-icon" class="fas fa-rotate-270 fa-sign-out-alt"></i>
</button>
<button id="add-rtmp-btn" type="button" class="btn btn-secondary btn-md rtmp-btn" data-toggle="modal" data-target="#add-external-source-modal">
Expand All @@ -79,13 +80,22 @@
</button>
</div>
<div class="modal-body">
<form id="rtmp-config">
form content goes here...
<form id="rtmp-config" action="" method="post" onSubmit="return false;">
<div class="form-group">
<label for="input_rtmp_url">RTMP Server URL</label>
<input type="url" class="form-control" id="input_rtmp_url" placeholder="Enter the RTMP Server URL" value="" required />
</div>
<div class="form-group">
<label for="input_private_key">Stream key</label>
<input type="text" class="form-control" id="input_private_key" placeholder="Enter stream key" required />
</div>
<input type="submit" value="Start RTMP" style="position:fixed; top:-999999px">
</form>
</div>
<div class="modal-footer">
<span id="rtmp-error-msg" class="error text-danger" style="display: none">Please complete the information!</span>
<button type="button" id="start-RTMP-broadcast" class="btn btn-primary">
<i class="fas fa-satellite-dish"></i>
<i class="fas fa-satellite-dish"></i>
</button>
</div>
</div>
Expand All @@ -98,17 +108,23 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="add-external-source-url-label"><i class="fas fa-broadcast-tower"></i> [add external url]</h5>
<h5 class="modal-title" id="add-external-source-url-label">
<i class="fas fa-broadcast-tower"></i> [add external url]
</h5>
<button id="hide-external-url-modal" type="button" class="close" data-dismiss="modal" data-reset="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="external-injest-config">
form content goes here...
<form id="external-inject-config">
<div class="form-group">
<label for="input_external_url">External URL</label>
<input type="url" class="form-control" id="input_external_url" placeholder="Enter the external URL" required>
</div>
</form>
</div>
<div class="modal-footer">
<span id="external-url-error" class="error text-danger" style="display: none">Please enter a valid external URL</span>
<button type="button" id="add-external-stream" class="btn btn-primary">
<i id="add-rtmp-icon" class="fas fa-plug"></i>
</button>
Expand All @@ -133,24 +149,6 @@
window.agoraCurrentRole = 'host';
window.agoraMode = 'audience';
window.userID = <?php echo $current_user->ID; ?>;

// default config for rtmp
var defaultConfigRTMP = {
width: <?php echo $videoSettings['external-width'] ?>,
height: <?php echo $videoSettings['external-height'] ?>,
videoBitrate: <?php echo $videoSettings['external-videoBitrate'] ?>,
videoFramerate: <?php echo $videoSettings['external-videoFramerate'] ?>,
lowLatency: <?php echo $videoSettings['external-lowLatency'] ?>,
audioSampleRate: <?php echo $videoSettings['external-audioSampleRate'] ?>,
audioBitrate: <?php echo $videoSettings['external-audioBitrate'] ?>,
audioChannels: <?php echo $videoSettings['external-audioChannels'] ?>,
videoGop: <?php echo $videoSettings['external-videoGop'] ?>,
videoCodecProfile: <?php echo $videoSettings['external-videoCodecProfile'] ?>,
userCount: 0,
userConfigExtraInfo: {},
backgroundColor: '<?php echo $videoSettings['external-backgroundColor'] ?>',
transcodingUsers: [],
};

// create client instance
window.agoraClient = AgoraRTC.createClient({mode: 'live', codec: 'vp8'}); // h264 better detail at a higher motion
Expand Down Expand Up @@ -184,6 +182,43 @@
}

window.externalBroadcastUrl = '';
// default config for rtmp
window.defaultConfigRTMP = {
width: <?php echo $videoSettings['external-width'] ?>,
height: <?php echo $videoSettings['external-height'] ?>,
videoBitrate: <?php echo $videoSettings['external-videoBitrate'] ?>,
videoFramerate: <?php echo $videoSettings['external-videoFramerate'] ?>,
lowLatency: <?php echo $videoSettings['external-lowLatency'] ?>,
audioSampleRate: <?php echo $videoSettings['external-audioSampleRate'] ?>,
audioBitrate: <?php echo $videoSettings['external-audioBitrate'] ?>,
audioChannels: <?php echo $videoSettings['external-audioChannels'] ?>,
videoGop: <?php echo $videoSettings['external-videoGop'] ?>,
videoCodecProfile: <?php echo $videoSettings['external-videoCodecProfile'] ?>,
userCount: 0,
userConfigExtraInfo: {},
backgroundColor: parseInt('<?php echo str_replace('#', '', $videoSettings['external-backgroundColor']) ?>', 16),
transcodingUsers: [{
uid: window.userID,
alpha: 1,
width: <?php echo $videoSettings['external-width'] ?>,
height: <?php echo $videoSettings['external-height'] ?>,
x: 0,
y: 0,
zOrder: 0
}],
};

window.injectStreamConfig = {
width: <?php echo $videoSettings['inject-width'] ?>,
height: <?php echo $videoSettings['inject-height'] ?>,
videoBitrate: <?php echo $videoSettings['inject-videoBitrate'] ?>,
videoFramerate: <?php echo $videoSettings['inject-videoFramerate'] ?>,
audioSampleRate: <?php echo $videoSettings['inject-audioSampleRate'] ?>,
audioBitrate: <?php echo $videoSettings['inject-audioBitrate'] ?>,
audioChannels: <?php echo $videoSettings['inject-audioChannels'] ?>,
videoGop: <?php echo $videoSettings['inject-videoGop'] ?>,
};


// set log level:
// -- .DEBUG for dev
Expand Down

1 comment on commit ede1c36

@jalamprea
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit implements #8 but it is not tested from the demo site.
I think we need to have some examples or documentation to use this functions because it is not intuitive or explicit in the backend nor the frontend.

Please sign in to comment.