First of all, thanks for answering so fast!. I tried to mimic the ipcameras code examples to a large degree. The way I’ve done is like this: First in frontend I call an ajax function with the identificators for the camera:
function getStream(camId,camName){
cameraId = camId;
$.ajax({
type: 'GET',
url: '/index/getStream',
data: { camId: cameraId, camName: camName },
success: function(response) {
console.log("getStream.response: "+response);
var jsonObject = JSON.parse(response);
thetoken = jsonObject.token;
subscribe(thetoken);
},
error: function(jqXHR) {
alert('Error: ' + jqXHR.status);
}
});
}
Then the mapped method manages the request and calls the needed methods:
@RequestMapping(value = "/index/getStream", method = RequestMethod.GET)
@ResponseBody
public String getStream(@RequestParam("camId") String camId,
@RequestParam("camName") String camName,
Model model){
String token = subscribe(rtspUri, camId, camName);//this is delivered to the frontend
}
The subscribe, createOpenViduSession and publishCameras methods are the same from the ipcameras github examples, except for the credentials part. Finally, the javascript “subscribe” function is:
// OpenVidu objects
var OV;
var session;
var videosContainer1 = document.getElementById("video01");
var videosContainer2 = document.getElementById("video02");
var subscriber;
function subscribe(token) {
// Initialize OpenVidu and Session objects
OV = new OpenVidu();
session = OV.initSession();
// Connect to session. We will receive all necessary events when success
session.connect(token)
.catch(error => {
var msg = 'There was an error connecting to the session. Code: ' + error.code + '. Message: ' + error
.message;
console.error(msg);
alert(msg);
});
// On every new Stream received...
session.on('streamCreated', event => {
// Subscribe to the Stream to receive it
// HTML video will be appended to a new element created inside <div id='camplayer'>
console.log("Stream Creado");
var videoDiv = document.createElement('div');
var stream = event.stream;
videoDiv.classList.add('video-container');
videoDiv.id = stream.streamId;
console.log("STREAM-ID: "+stream.streamId);
videosContainer1.appendChild(videoDiv);
// Append video inside our brand new <div> element
subscriber = session.subscribe(stream, videoDiv, {insertMode: 'REPLACE'});
// When the HTML video has been appended to DOM...
subscriber.on('videoElementCreated', ev => {
// ...start loader
var loader = document.createElement('div');
loader.classList.add('loader');
const videoElements = document.getElementsByTagName("video");
for (const vs of videoElements){
vs.setAttribute('muted', 'true');
vs.setAttribute('autoplay', 'true');
}
ev.element.parentNode.insertBefore(loader, ev.element.nextSibling);
});
// When the HTML video starts playing...
subscriber.on('streamPlaying', ev => {
// ...remove loader
var cameraVideoElement = subscriber.videos[0].video;
//cameraVideoElement.parentNode.removeChild(cameraVideoElement.nextSibling);
videosContainer1.removeChild(cameraVideoElement.nextSibling);
$(".loader").remove();
// ... mute video if browser blocked autoplay
autoplayMutedVideoIfBlocked(cameraVideoElement);
});
// When the HTML video has been removed from DOM...
subscriber.on('videoElementDestroyed', ev => {
// ...remove the HTML elements related to the destroyed video
var videoContainer = document.getElementById(stream.streamId);
videoContainer.parentNode.removeChild(videoContainer);
console.log("videoElementDestroyed");
});
});
// On every asynchronous exception...
session.on('exception', (exception) => {
console.warn(exception);
});
}
For changing the live video to a pre-recorded video first I call another ajax javascript function:
function playFile(times){
$( "#playFile" ).prop( "disabled", true );
$( "#getFile" ).prop( "disabled", true );
$.ajax({
type: 'GET',
url: '/index/playFileOnDemand',
data: { cameraReference: times },
success: function(token) {
subscribe(token);
},
error: function(jqXHR) {
alert('Error: ' + jqXHR.status);
}
});
};
And the method in the backend is:
public String playFileOnDemand(String cameraReference) throws OpenViduJavaClientException, OpenViduHttpException {
if(OV == null || OVSession == null){
return null;
}
String[] values = cameraReference.split("##");
String camId = values[0];
String startTime = values[1];
String rtsp01 = startTime.split("//")[0];
String rtsp02 = startTime.split("//")[1];
String finalRtsp = rtsp01 + "//admin:'Isa2107!'@" + rtsp02;
try {
ConnectionProperties connectionProperties = new ConnectionProperties.Builder()
.type(ConnectionType.IPCAM)
.data(camId)
.rtspUri(finalRtsp)
.adaptativeBitrate(true)
.onlyPlayWithSubscribers(true)
.record(false)
.build();
return OVSession.createConnection(connectionProperties).getToken();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
As a side note, I feed OpenVidu with rtsp uris, OpenVidu is not connecting directly to the cameras. I have a rest server that provides all the rtsp uris needed, both the live rtsp and the pre-recorded video rtsp.