Skip to content

Commit

Permalink
Add stop streaming feature
Browse files Browse the repository at this point in the history
  • Loading branch information
SangwonOh committed Feb 10, 2023
1 parent f4c925b commit 227f1f3
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 90 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import OvenLiveKit from 'ovenlivekit'
This is the simplest example of sending a device media stream such as a webcam to OvenMediaEngine's WebRTC Provider.
```JavaScript
// Initialize OvenLiveKit
let ovenLivekit = OvenLiveKit.create();
const ovenLivekit = OvenLiveKit.create();

// Get media stream from user device
ovenLivekit.getUserMedia().then(function () {
Expand Down Expand Up @@ -104,7 +104,7 @@ var config = {
}

// Initialize ovenLivekit instance
let ovenLivekit = OvenLiveKit.create(config);
const ovenLivekit = OvenLiveKit.create(config);

// Release all resources and destroy the instance
ovenLivekit.remove();
Expand Down Expand Up @@ -219,7 +219,7 @@ OvenLiveKit also provides APIs to control a media stream from a user device.
```
```JavaScript
// Create instance
let ovenLivekit = OvenLiveKit.create();
const ovenLivekit = OvenLiveKit.create();

// Attaching video element for playing device stream
ovenLivekit.attachMedia(document.getElementById('myVideo'));
Expand Down Expand Up @@ -254,7 +254,7 @@ ovenLivekit.getUserMedia(constraints).then(function (stream) {
Congrats on getting the media stream from the user device and then ready to stream into OvenMediaEngine.
```JavaScript
// Create instance
let ovenLivekit = OvenLiveKit.create();
const ovenLivekit = OvenLiveKit.create();

ovenLivekit.getUserMedia().then(function () {

Expand Down Expand Up @@ -293,6 +293,9 @@ ovenLivekit.getUserMedia().then(function () {
- String: String you want to append to a=fmtp of SDP.
- If set video format is appended to the a=fmtp sections of SDP.

#### `instance.stopStreaming()`
- Close peer connection and websocket associated with OvenMediaEngine.

## For more information
* [WebRTC Input in OvenPlayer Demo](https://demo.ovenplayer.com/demo_input.html)
* Test Player based on OvenPlayer.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ovenlivekit",
"version": "1.0.3",
"version": "1.0.4",
"description": "OvenLiveKit for Web is an open source JavaScript SDK suite for live streaming from web browsers to OvenMediaEngine.",
"main": "dist/OvenLiveKit.min.js",
"scripts": {
Expand Down
153 changes: 68 additions & 85 deletions src/OvenLiveKit.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const OvenLiveKit = {};

const version = '1.0.4';
const logHeader = 'OvenLiveKit.js :';
const logEventHeader = 'OvenLiveKit.js ====';

Expand Down Expand Up @@ -33,15 +34,6 @@ function findIp(string) {
return result;
}

function checkIOSVersion() {
var agent = window.navigator.userAgent,
start = agent.indexOf('OS ');
if ((agent.indexOf('iPhone') > -1 || agent.indexOf('iPad') > -1) && start > -1) {
return window.Number(agent.substr(start + 3, 3).replace('_', '.'));
}
return 0;
}

function getFormatNumber(sdp, format) {

const lines = sdp.split('\r\n');
Expand Down Expand Up @@ -143,13 +135,11 @@ function gotDevices(deviceInfos) {

function initConfig(instance, options) {

instance.stream = null;
instance.inputStream = null;
instance.webSocket = null;
instance.peerConnection = null;
instance.connectionConfig = {};

instance.status = 'creating';

instance.videoElement = null;
instance.connectionUrl = null;

Expand All @@ -159,7 +149,6 @@ function initConfig(instance, options) {
} else {
instance.callbacks = {};
}

}

function addMethod(instance) {
Expand All @@ -186,14 +175,14 @@ function addMethod(instance) {
};
}

console.info(logHeader, 'Requested Constraint To Input Devices', constraints);
console.info(logHeader, 'Request Stream To Input Devices With Constraints', constraints);

return navigator.mediaDevices.getUserMedia(constraints)
.then(function (stream) {

console.info(logHeader, 'Received Media Stream From Input Device', stream);

instance.stream = stream;
instance.inputStream = stream;

let elem = instance.videoElement;

Expand Down Expand Up @@ -230,14 +219,14 @@ function addMethod(instance) {
constraints = {};
}

console.info(logHeader, 'Requested Constraint To Display', constraints);
console.info(logHeader, 'Request Stream To Display With Constraints', constraints);

return navigator.mediaDevices.getDisplayMedia(constraints)
.then(function (stream) {

console.info(logHeader, 'Received Media Stream From Display', stream);

instance.stream = stream;
instance.inputStream = stream;

let elem = instance.videoElement;

Expand Down Expand Up @@ -371,10 +360,9 @@ function addMethod(instance) {

webSocket.onclose = function (e) {

if (!instance.removing) {
if (!instance.webSocketClosedByUser) {

if (instance.callbacks.connectionClosed) {

instance.callbacks.connectionClosed('websocket', e);
}
}
Expand Down Expand Up @@ -565,21 +553,12 @@ function addMethod(instance) {
instance.peerConnection = peerConnection;

// set local stream
instance.stream.getTracks().forEach(function (track) {
instance.inputStream.getTracks().forEach(function (track) {

console.info(logHeader, 'Add Track To Peer Connection', track);
peerConnection.addTrack(track, instance.stream);
peerConnection.addTrack(track, instance.inputStream);
});


if (checkIOSVersion() >= 15) {
const formatNumber = getFormatNumber(offer.sdp, 'H264');

if (formatNumber > 0) {
offer.sdp = removeFormat(offer.sdp, formatNumber);
}
}

if (instance.connectionConfig.maxVideoBitrate) {

// if bandwith limit is set. modify sdp from ome to limit acceptable bandwidth of ome
Expand All @@ -599,16 +578,6 @@ function addMethod(instance) {
peerConnection.createAnswer()
.then(function (answer) {

if (checkIOSVersion() >= 15) {

const formatNumber = getFormatNumber(answer.sdp, 'H264');

if (formatNumber > 0) {

answer.sdp = removeFormat(answer.sdp, formatNumber);
}
}

if (instance.connectionConfig.sdp && instance.connectionConfig.sdp.appendFmtp) {

answer.sdp = appendFmtp(answer.sdp);
Expand Down Expand Up @@ -651,8 +620,6 @@ function addMethod(instance) {

if (e.candidate && e.candidate.candidate) {

console.info(logHeader, 'Candidate Sent', '\n', e.candidate.candidate, '\n', e);

sendMessage(instance.webSocket, {
id: id,
peer_id: peerId,
Expand All @@ -675,16 +642,13 @@ function addMethod(instance) {
if (state === 'connected') {

if (instance.callbacks.connected) {

console.info(logHeader, 'Iceconnection Connected', e);
instance.callbacks.connected(e);
}
}

if (state === 'failed' || state === 'disconnected' || state === 'closed') {

if (instance.callbacks.connectionClosed) {

console.error(logHeader, 'Iceconnection Closed', e);
instance.callbacks.connectionClosed('ice', e);
}
Expand Down Expand Up @@ -713,6 +677,49 @@ function addMethod(instance) {
}
}

function closePeerConnection() {
if (instance.peerConnection) {

// remove tracks from peer connection
instance.peerConnection.getSenders().forEach(function (sender) {
instance.peerConnection.removeTrack(sender);
});

instance.peerConnection.close();
instance.peerConnection = null;
delete instance.peerConnection;
}
}

function closeWebSocket() {

if (instance.webSocket) {

instance.webSocket.close();
instance.webSocket = null;
delete instance.webSocket;
}
}

function closeInputStream() {
// release video, audio stream
if (instance.inputStream) {

instance.inputStream.getTracks().forEach(track => {

track.stop();
instance.inputStream.removeTrack(track);
});

if (instance.videoElement) {
instance.videoElement.srcObject = null;
}

instance.inputStream = null;
delete instance.inputStream;
}
}

// instance methods
instance.attachMedia = function (videoElement) {

Expand Down Expand Up @@ -741,63 +748,39 @@ function addMethod(instance) {
initWebSocket(connectionUrl);
};

instance.remove = function () {

instance.removing = true;
instance.stopStreaming = function () {

// first release peer connection with ome
if (instance.peerConnection) {
instance.webSocketClosedByUser = true;

// remove tracks from peer connection
instance.peerConnection.getSenders().forEach(function (sender) {
instance.peerConnection.removeTrack(sender);
});

instance.peerConnection.close();
instance.peerConnection = null;
delete instance.peerConnection;
}

// release video, audio stream
if (instance.stream) {

instance.stream.getTracks().forEach(track => {

track.stop();
instance.stream.removeTrack(track);
});

if (instance.videoElement) {
instance.videoElement.srcObject = null;
}

instance.stream = null;
delete instance.stream;
}
closeWebSocket();
closePeerConnection();
};

// release websocket
if (instance.webSocket) {
instance.remove = function () {

instance.webSocket.close();
instance.webSocket = null;
delete instance.webSocket;
}
instance.webSocketClosedByUser = true;

instance.status = 'removed';
closeWebSocket();
closePeerConnection();
closeInputStream();

console.info(logEventHeader, 'Removed');

};
}

OvenLiveKit.getVersion = function () {
return version;
}

// static methods
OvenLiveKit.create = function (options) {

console.info(logEventHeader, 'Create WebRTC Input v1.0.2');
console.info(logEventHeader, 'Create WebRTC Input ' + version);

let instance = {};

instance.removing = false;
instance.webSocketClosedByUser = false;

initConfig(instance, options);
addMethod(instance);
Expand Down

0 comments on commit 227f1f3

Please sign in to comment.