-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from red5pro/feature/test-append
added publish-append example
- Loading branch information
Showing
5 changed files
with
241 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Publish Stream Recording - Append | ||
This example demonstrates appended recording of the published stream to the server. | ||
|
||
**Please refer to the [Basic Publisher Documentation](../publish/README.md) to learn more about the basic setup.** | ||
|
||
### Example Code | ||
- **[index.html](index.html)** | ||
- **[index.js](index.js)** | ||
|
||
> These examples use the WebRTC-based Publisher implementation from the Red5 Pro HTML SDK. However, there is failover support to allow for Flash-base publisher on unsupported browsers. | ||
## Recording | ||
To record a published stream, modify the `streamMode` configuration attribute provided upon initialization of the Publisher: | ||
|
||
```js | ||
var defaultConfiguration = { | ||
protocol: 'ws', | ||
port: 8081, | ||
app: 'live', | ||
streamMode: 'append' | ||
}; | ||
``` | ||
|
||
<sup> | ||
[index.js #22](index.js#L22) | ||
</sup> | ||
|
||
The following are accepted values for the `streamMode` configuration attribute: | ||
|
||
* **live** | ||
* **record** | ||
* **append** | ||
|
||
The default value is `live`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
{{> meta title='Publish Append Test'}} | ||
{{> header-scripts}} | ||
{{> header-stylesheets}} | ||
</head> | ||
<body> | ||
<div id="app"> | ||
{{> version }} | ||
{{> settings-link}} | ||
{{> test-info testTitle='Publish Append Test'}} | ||
{{> status-field-publisher}} | ||
{{> statistics-field}} | ||
<div class="centered"> | ||
<video id="red5pro-publisher-video" controls class="video-element" muted></video> | ||
</div> | ||
</div> | ||
{{> body-scripts}} | ||
<script src="index.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
(function(window, document, red5pro, PublisherBase /* see: src/static/script/main.js */) { | ||
'use strict'; | ||
|
||
var serverSettings = (function() { | ||
var settings = sessionStorage.getItem('r5proServerSettings'); | ||
try { | ||
return JSON.parse(settings); | ||
} | ||
catch (e) { | ||
console.error('Could not read server settings from sessionstorage: ' + e.message); | ||
} | ||
return {}; | ||
})(); | ||
|
||
var configuration = (function () { | ||
var conf = sessionStorage.getItem('r5proTestBed'); | ||
try { | ||
return JSON.parse(conf); | ||
} | ||
catch (e) { | ||
console.error('Could not read testbed configuration from sessionstorage: ' + e.message); | ||
} | ||
return {} | ||
})(); | ||
|
||
var targetPublisher; | ||
var targetView; | ||
|
||
var updateStatusFromEvent = window.red5proHandlePublisherEvent; // defined in src/template/partial/status-field-publisher.hbs | ||
var streamTitle = document.getElementById('stream-title'); | ||
var statisticsField = document.getElementById('statistics-field'); | ||
|
||
var protocol = serverSettings.protocol; | ||
var isSecure = protocol == 'https'; | ||
function getSocketLocationFromProtocol () { | ||
return !isSecure | ||
? {protocol: 'ws', port: serverSettings.wsport} | ||
: {protocol: 'wss', port: serverSettings.wssport}; | ||
} | ||
|
||
var defaultConfiguration = { | ||
protocol: getSocketLocationFromProtocol().protocol, | ||
port: getSocketLocationFromProtocol().port, | ||
app: 'live', | ||
streamMode: 'append' | ||
}; | ||
|
||
function onBitrateUpdate (bitrate, packetsSent) { | ||
statisticsField.innerText = 'Bitrate: ' + Math.floor(bitrate) + '. Packets Sent: ' + packetsSent + '.'; | ||
} | ||
|
||
function onPublisherEvent (event) { | ||
console.log('[Red5ProPublisher] ' + event.type + '.'); | ||
updateStatusFromEvent(event); | ||
} | ||
function onPublishFail (message) { | ||
console.error('[Red5ProPublisher] Publish Error :: ' + message); | ||
} | ||
function onPublishSuccess (publisher) { | ||
console.log('[Red5ProPublisher] Publish Complete.'); | ||
try { | ||
window.trackBitrate(publisher.getPeerConnection(), onBitrateUpdate); | ||
} | ||
catch(e) { | ||
// | ||
} | ||
} | ||
function onUnpublishFail (message) { | ||
console.error('[Red5ProPublisher] Unpublish Error :: ' + message); | ||
} | ||
function onUnpublishSuccess () { | ||
console.log('[Red5ProPublisher] Unpublish Complete.'); | ||
} | ||
|
||
function getUserMediaConfiguration () { | ||
return { | ||
audio: configuration.useAudio ? configuration.userMedia.audio : false, | ||
video: configuration.useVideo ? configuration.userMedia.video : false, | ||
frameRate: configuration.frameRate | ||
}; | ||
} | ||
|
||
function determinePublisher () { | ||
|
||
var config = Object.assign({}, | ||
configuration, | ||
defaultConfiguration, | ||
getUserMediaConfiguration()); | ||
var rtcConfig = Object.assign({}, config, { | ||
protocol: getSocketLocationFromProtocol().protocol, | ||
port: getSocketLocationFromProtocol().port, | ||
streamName: config.stream1, | ||
streamType: 'webrtc' | ||
}); | ||
var rtmpConfig = Object.assign({}, config, { | ||
protocol: 'rtmp', | ||
port: serverSettings.rtmpport, | ||
streamName: config.stream1, | ||
width: config.cameraWidth, | ||
height: config.cameraHeight, | ||
swf: '../../lib/red5pro/red5pro-publisher.swf', | ||
swfobjectURL: '../../lib/swfobject/swfobject.js', | ||
productInstallURL: '../../lib/swfobject/playerProductInstall.swf' | ||
}); | ||
var publishOrder = config.publisherFailoverOrder | ||
.split(',') | ||
.map(function (item) { | ||
return item.trim() | ||
}); | ||
|
||
return PublisherBase.determinePublisher({ | ||
rtc: rtcConfig, | ||
rtmp: rtmpConfig | ||
}, publishOrder); | ||
} | ||
|
||
function preview (publisher, requiresGUM) { | ||
var elementId = 'red5pro-publisher-video'; | ||
var gUM = getUserMediaConfiguration(); | ||
return PublisherBase.preview(publisher, elementId, requiresGUM ? gUM : undefined); | ||
} | ||
|
||
function publish (publisher, view, streamName) { | ||
streamTitle.innerText = streamName; | ||
targetPublisher = publisher; | ||
targetView = view; | ||
return new Promise(function (resolve, reject) { | ||
PublisherBase.publish(publisher, streamName) | ||
.then(function () { | ||
onPublishSuccess(publisher); | ||
}) | ||
.catch(function (error) { | ||
reject(error); | ||
}) | ||
}); | ||
} | ||
|
||
function unpublish () { | ||
return new Promise(function (resolve, reject) { | ||
var view = targetView; | ||
var publisher = targetPublisher; | ||
PublisherBase.unpublish(publisher, view) | ||
.then(function () { | ||
onUnpublishSuccess(); | ||
resolve(); | ||
}) | ||
.catch(function (error) { | ||
var jsonError = typeof error === 'string' ? error : JSON.stringify(error, 2, null); | ||
onUnpublishFail('Unmount Error ' + jsonError); | ||
reject(error); | ||
}); | ||
}); | ||
} | ||
|
||
// Kick off. | ||
determinePublisher() | ||
.then(function (payload) { | ||
var requiresPreview = payload.requiresPreview; | ||
var publisher = payload.publisher; | ||
publisher.on('*', onPublisherEvent); | ||
return preview(publisher, requiresPreview); | ||
}) | ||
.then(function (payload) { | ||
var publisher = payload.publisher; | ||
var view = payload.view; | ||
return publish(publisher, view, configuration.stream1); | ||
}) | ||
.catch(function (error) { | ||
var jsonError = typeof error === 'string' ? error : JSON.stringify(error, null, 2); | ||
console.error('[Red5ProPublisher] :: Error in publishing - ' + jsonError); | ||
onPublishFail(jsonError); | ||
}); | ||
|
||
window.addEventListener('beforeunload', function() { | ||
function clearRefs () { | ||
targetPublisher.off('*', onPublisherEvent); | ||
targetView = targetPublisher = undefined; | ||
} | ||
unpublish().then(clearRefs).catch(clearRefs); | ||
window.untrackBitrate(); | ||
}); | ||
})(this, document, window.red5prosdk, new window.R5ProBase.Publisher()); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters