je umetniška instalacija, ki je del razstave Nevidni sopotnik v Mestni galeriji Nova Gorica. Spodnja konzola vam omogoča upravljanje tamkajšnjega lebdečega objekta.
-
-
+
+
+
diff --git a/www/js/streaming.js b/www/js/streaming.js
index 0c8f428..651b913 100644
--- a/www/js/streaming.js
+++ b/www/js/streaming.js
@@ -1,23 +1,3 @@
-// We import the settings.js file to know which address we should contact
-// to talk to Janus, and optionally which STUN/TURN servers should be
-// used as well. Specifically, that file defines the "server" and
-// "iceServers" properties we'll pass when creating the Janus session.
-
-var janus = null;
-var streaming = null;
-var opaqueId = "streamingtest-"+Janus.randomString(12);
-
-var remoteTracks = {}, dataMid = null;
-var bitrateTimer = {};
-var spinner = {};
-
-var simulcastStarted = {}, svcStarted = {};
-
-var streamsList = {};
-
-// Kar fiksiramo na 666
-var selectedStream = 666;
-
window.addEventListener('DOMContentLoaded', function () {
var predvajaj = document.querySelector('#predvajaj');
@@ -32,340 +12,38 @@ window.addEventListener('DOMContentLoaded', function () {
// Funkcije za veckratno rabo
function omogociGumbe(kdaj) {
setTimeout(function () {
- vsiGumbi.forEach(function (gEl) {
+ vsiGumbi.forEach(function (gEl) {
gEl.toggleAttribute('disabled', false);
- });
+ });
}, kdaj);
}
function onemogociGumbe() {
vsiGumbi.forEach(function (gEl) {
- gEl.toggleAttribute('disabled', true);
+ gEl.toggleAttribute('disabled', true);
});
}
-
- function gremoLevo() {
+ // Gumbi levo in desno
+ gLevo.addEventListener('click', function () {
console.log('GREMO LEVO!');
window.peljiLevo();
- onemogociGumbe();
- omogociGumbe(DOLZINA + PAVZA);
- }
- function gremoRavno() {
- console.log('GREMO RAVNO!');
- window.peljiRavno();
onemogociGumbe();
omogociGumbe(DOLZINA + PAVZA);
- }
- function gremoDesno() {
+ });
+ gDesno.addEventListener('click', function () {
console.log('GREMO DESNO!');
window.peljiDesno();
onemogociGumbe();
omogociGumbe(DOLZINA + PAVZA);
- }
+ });
+ gRavno.addEventListener('click', function () {
+ console.log('GREMO RAVNO!');
+ window.peljiRavno();
- // Initialize the library (all console debuggers enabled)
- Janus.init({debug: "all", callback: function() {
- // Make sure the browser supports WebRTC
- if(!Janus.isWebrtcSupported()) {
- console.log("ERROR cannot start; no WebRTC support... ");
- return;
- }
- // Create session
- janus = new Janus({
- server: server,
- iceServers: iceServers,
- // Should the Janus API require authentication, you can specify either the API secret or user token here too
- // token: "mytoken",
- // or
- // apisecret: "serversecret",
- success: function() {
- // Attach to Streaming plugin
- janus.attach({
- plugin: "janus.plugin.streaming",
- opaqueId: opaqueId,
- success: function(pluginHandle) {
- streaming = pluginHandle;
- Janus.log("Plugin attached! (" + streaming.getPlugin() + ", id=" + streaming.getId() + ")");
-
- // Setup streaming session
- updateStreamsList();
-
- /* ustavitev neka?
- for(var i in bitrateTimer)
- clearInterval(bitrateTimer[i]);
- bitrateTimer = {};
- janus.destroy();
- */
-
-
- // Kar zacnimo stream
- startStream();
- },
- error: function(error) {
- Janus.error(" -- Error attaching plugin... ", error);
- },
- iceState: function(state) {
- Janus.log("ICE state changed to " + state);
- },
- webrtcState: function(on) {
- Janus.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
- if (on) {
- // Gumbi levo in desno
- gLevo.addEventListener('click', gremoLevo);
- gDesno.addEventListener('click', gremoDesno);
- gRavno.addEventListener('click', gremoRavno);
- } else {
- gLevo.removeEventListener('click', gremoLevo);
- gDesno.removeEventListener('click', gremoDesno);
- gRavno.removeEventListener('click', gremoRavno);
- }
- },
- slowLink: function(uplink, lost, mid) {
- Janus.warn("Janus reports problems " + (uplink ? "sending" : "receiving") +
- " packets on mid " + mid + " (" + lost + " lost packets)");
- },
- onmessage: function(msg, jsep) {
- Janus.debug(" ::: Got a message :::", msg);
- var result = msg["result"];
- if(result) {
- if(result["status"]) {
- var status = result["status"];
-// if(status === 'starting')
-// else if(status === 'started')
-// else if(status === 'stopped')
- if(status === 'stopped') {
- stopStream();
- }
- } else if(msg["streaming"] === "event") {
- // Does this event refer to a mid in particular?
- var mid = result["mid"] ? result["mid"] : "0";
- // Is simulcast in place?
- var substream = result["substream"];
- var temporal = result["temporal"];
- if((substream !== null && substream !== undefined) || (temporal !== null && temporal !== undefined)) {
- if(!simulcastStarted[mid]) {
- simulcastStarted[mid] = true;
- }
- }
- // Is VP9/SVC in place?
- var spatial = result["spatial_layer"];
- temporal = result["temporal_layer"];
- }
- } else if(msg["error"]) {
- console.log('NAPAKA', msg["error"]);
- stopStream();
- return;
- }
- if(jsep) {
- Janus.debug("Handling SDP as well...", jsep);
- var stereo = (jsep.sdp.indexOf("stereo=1") !== -1);
- // Offer from the plugin, let's answer
- streaming.createAnswer({
- jsep: jsep,
- // We only specify data channels here, as this way in
- // case they were offered we'll enable them. Since we
- // don't mention audio or video tracks, we autoaccept them
- // as recvonly (since we won't capture anything ourselves)
- tracks: [{ type: 'data' }],
- customizeSdp: function(jsep) {
- if(stereo && jsep.sdp.indexOf("stereo=1") == -1) {
- // Make sure that our offer contains stereo too
- jsep.sdp = jsep.sdp.replace("useinbandfec=1", "useinbandfec=1;stereo=1");
- }
- },
- success: function(jsep) {
- Janus.debug("Got SDP!", jsep);
- var body = { request: "start" };
- streaming.send({ message: body, jsep: jsep });
- },
- error: function(error) {
- Janus.error("WebRTC error:", error);
- }
- });
- }
- },
- onremotetrack: function(track, mid, on, metadata) {
- Janus.debug("Remote track (mid=" + mid + ") " + (on ? "added" : "removed") +
- (metadata ? " (" + metadata.reason + ") ": "") + ":", track
- );
-
- var mstreamId = "mstream"+mid;
- if(streamsList[selectedStream] && streamsList[selectedStream].legacy) {
- mstreamId = "mstream0";
- }
-
- console.log('dodam?', on);
- if(true) {
- // If we're here, a new track was added
- var stream = null;
-
- // New video track: create a stream out of it
- stream = new MediaStream([track]);
- console.log('MOJ PRETOK!', stream, track);
- remoteTracks[mid] = stream;
- Janus.log("Created remote video stream:", stream);
-
- var vidEl = document.querySelector('#videofeed');
- var zaslonEl = document.querySelector('.zaslon');
-
- /* bitrate in resolucija
- if(!bitrateTimer[mid]) {
- bitrateTimer[mid] = setInterval(function() {
- // Display updated bitrate, if supported
- var bitrate = streaming.getBitrate(mid);
- console.log('bitrate:', bitrate);
-
- // Check if the resolution changed too
- var width = vidEl.videoWidth;
- var height = vidEl.videoHeight;
- if (width > 0 && height > 0) console.log('resolucija', width+'x'+height);
- }, 1000);
- }
- */
- console.log('dodajam pretok', vidEl, stream);
- Janus.attachMediaStream(vidEl, stream);
-
- vidEl.addEventListener('canplay', function () {
- console.log('lahko predvajam!');
- zaslonEl.classList.remove('cakam');
- });
-
- // Moramo kliknit za predvajanje :/
- // predvajaj.style.display = 'block';
- predvajaj.addEventListener('click', function () {
- predvajaj.style.display = 'none';
- vidEl.play();
- });
-
- vidEl.addEventListener('play', function () {
- glavno.classList.add('predvajam');
- predvajaj.style.display = 'none';
- });
-
- //vidEl.play();
- }
- },
- ondataopen: function(data) {
- Janus.log("The DataChannel is available!");
- window.dataKanal = data;
- },
- ondata: function(data) {
- Janus.debug("We got data from the DataChannel!", data);
- console.log('DUBU DATA', data);
- obdelajData(data);
- },
- oncleanup: function() {
- Janus.log(" ::: Got a cleanup notification :::");
- for(var i in bitrateTimer)
- clearInterval(bitrateTimer[i]);
- bitrateTimer = {};
- remoteTracks = {};
- dataMid = null;
- }
- });
- },
- error: function(error) {
- Janus.error(error);
- },
- destroyed: function() {
- window.location.reload();
- }
- });
-}});
-});
-
-function updateStreamsList() {
- var body = { request: "list" };
- Janus.debug("Sending message:", body);
- streaming.send({ message: body, success: function(result) {
- if(!result) {
- console.log("Error: Got no response to our query for available streams");
- return;
- }
- if(result["list"]) {
- var list = result["list"];
- if(list && Array.isArray(list)) {
- list.sort(function(a, b) {
- if(!a || a.id < (b ? b.id : 0))
- return -1;
- if(!b || b.id < (a ? a.id : 0))
- return 1;
- return 0;
- });
- }
- Janus.log("Got a list of available streams:", list);
- streamsList = {};
- for(var mp in list) {
- Janus.debug(" >> [" + list[mp]["id"] + "] " + list[mp]["description"] + " (" + list[mp]["type"] + ")");
- // Check the nature of the available streams, and if there are some multistream ones
- list[mp].legacy = true;
- if(list[mp].media) {
- var audios = 0, videos = 0;
- for(var mi in list[mp].media) {
- if(!list[mp].media[mi])
- continue;
- if(list[mp].media[mi].type === "audio")
- audios++;
- else if(list[mp].media[mi].type === "video")
- videos++;
- if(audios > 1 || videos > 1) {
- list[mp].legacy = false;
- break;
- }
- }
- }
- // Keep track of all the available streams
- streamsList[list[mp]["id"]] = list[mp];
- }
-
- // Dajmo kar zacet
- startStream();
- }
- }});
-}
-
-function getStreamInfo() {
- // Send a request for more info on the mountpoint we subscribed to
- var body = { request: "info", id: parseInt(selectedStream) || selectedStream };
- streaming.send({ message: body, success: function(result) {
- if(result && result.info && result.info.metadata) {
- console.log('STREAM META', result.info.metadata);
- }
- }});
-}
-
-function startStream() {
- Janus.log("Selected video id #" + selectedStream);
- console.log('zacenjam', selectedStream, streamsList[selectedStream]);
- if(!selectedStream || !streamsList[selectedStream]) {
- console.log("Error: No stream selected to start");
- return;
- }
-
- if(streamsList[selectedStream].legacy) {
- for(mi in streamsList[selectedStream].media) {
- // Add a new panel
- var type = streamsList[selectedStream].media[mi].type;
- if(type === "video") {
- mid = streamsList[selectedStream].media[mi].mid;
- break;
- }
- }
- }
- // Prepare the request to start streaming and send it
- var body = { request: "watch", id: parseInt(selectedStream) || selectedStream };
- streaming.send({ message: body });
- getStreamInfo();
-}
-
-function stopStream() {
- streaming.send({ message: body });
- streaming.hangup();
-}
-
-function obdelajData(data) {
- console.log('obdelam webrtc podatke', data);
+ onemogociGumbe();
+ omogociGumbe(DOLZINA + PAVZA);
+ });
}
diff --git a/www/js/streaming.js.bak b/www/js/streaming.js.bak
new file mode 100644
index 0000000..9bc5092
--- /dev/null
+++ b/www/js/streaming.js.bak
@@ -0,0 +1,367 @@
+// We import the settings.js file to know which address we should contact
+// to talk to Janus, and optionally which STUN/TURN servers should be
+// used as well. Specifically, that file defines the "server" and
+// "iceServers" properties we'll pass when creating the Janus session.
+
+var janus = null;
+var streaming = null;
+var opaqueId = "streamingtest-"+Janus.randomString(12);
+
+var remoteTracks = {}, dataMid = null;
+var bitrateTimer = {};
+var spinner = {};
+
+var simulcastStarted = {}, svcStarted = {};
+
+var streamsList = {};
+
+// Kar fiksiramo na 666
+var selectedStream = 666;
+
+window.addEventListener('DOMContentLoaded', function () {
+
+ var predvajaj = document.querySelector('#predvajaj');
+ var gumbi = document.querySelector('#predvajaj');
+ var glavno = document.querySelector('#glavno');
+
+ var gLevo = document.querySelector('#levo');
+ var gDesno = document.querySelector('#desno');
+ var gRavno = document.querySelector('#ravno');
+ var vsiGumbi = [gLevo, gDesno, gRavno];
+
+ // Funkcije za veckratno rabo
+ function omogociGumbe(kdaj) {
+ setTimeout(function () {
+ vsiGumbi.forEach(function (gEl) {
+ gEl.toggleAttribute('disabled', false);
+ });
+ }, kdaj);
+ }
+
+ function onemogociGumbe() {
+ vsiGumbi.forEach(function (gEl) {
+ gEl.toggleAttribute('disabled', true);
+ });
+ }
+
+ // Initialize the library (all console debuggers enabled)
+ Janus.init({debug: "all", callback: function() {
+ // Make sure the browser supports WebRTC
+ if(!Janus.isWebrtcSupported()) {
+ console.log("ERROR cannot start; no WebRTC support... ");
+ return;
+ }
+ // Create session
+ janus = new Janus({
+ server: server,
+ iceServers: iceServers,
+ // Should the Janus API require authentication, you can specify either the API secret or user token here too
+ // token: "mytoken",
+ // or
+ // apisecret: "serversecret",
+ success: function() {
+ // Attach to Streaming plugin
+ janus.attach({
+ plugin: "janus.plugin.streaming",
+ opaqueId: opaqueId,
+ success: function(pluginHandle) {
+ streaming = pluginHandle;
+ Janus.log("Plugin attached! (" + streaming.getPlugin() + ", id=" + streaming.getId() + ")");
+
+ // Setup streaming session
+ updateStreamsList();
+
+ /* ustavitev neka?
+ for(var i in bitrateTimer)
+ clearInterval(bitrateTimer[i]);
+ bitrateTimer = {};
+ janus.destroy();
+ */
+
+
+ // Kar zacnimo stream
+ startStream();
+ },
+ error: function(error) {
+ Janus.error(" -- Error attaching plugin... ", error);
+ },
+ iceState: function(state) {
+ Janus.log("ICE state changed to " + state);
+ },
+ webrtcState: function(on) {
+ Janus.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
+ if (on) {
+ // Gumbi levo in desno
+ gLevo.addEventListener('click', function () {
+ console.log('GREMO LEVO!');
+ window.peljiLevo();
+
+ onemogociGumbe();
+ omogociGumbe(DOLZINA + PAVZA);
+ });
+ gDesno.addEventListener('click', function () {
+ console.log('GREMO DESNO!');
+ window.peljiDesno();
+
+ onemogociGumbe();
+ omogociGumbe(DOLZINA + PAVZA);
+ });
+ gRavno.addEventListener('click', function () {
+ console.log('GREMO RAVNO!');
+ window.peljiRavno();
+
+ onemogociGumbe();
+ omogociGumbe(DOLZINA + PAVZA);
+ });
+ } else {
+ gLevo.removeEventListener('click');
+ gDesno.removeEventListener('click');
+ gRavno.removeEventListener('click');
+ }
+ },
+ slowLink: function(uplink, lost, mid) {
+ Janus.warn("Janus reports problems " + (uplink ? "sending" : "receiving") +
+ " packets on mid " + mid + " (" + lost + " lost packets)");
+ },
+ onmessage: function(msg, jsep) {
+ Janus.debug(" ::: Got a message :::", msg);
+ var result = msg["result"];
+ if(result) {
+ if(result["status"]) {
+ var status = result["status"];
+// if(status === 'starting')
+// else if(status === 'started')
+// else if(status === 'stopped')
+ if(status === 'stopped') {
+ stopStream();
+ }
+ } else if(msg["streaming"] === "event") {
+ // Does this event refer to a mid in particular?
+ var mid = result["mid"] ? result["mid"] : "0";
+ // Is simulcast in place?
+ var substream = result["substream"];
+ var temporal = result["temporal"];
+ if((substream !== null && substream !== undefined) || (temporal !== null && temporal !== undefined)) {
+ if(!simulcastStarted[mid]) {
+ simulcastStarted[mid] = true;
+ }
+ }
+ // Is VP9/SVC in place?
+ var spatial = result["spatial_layer"];
+ temporal = result["temporal_layer"];
+ }
+ } else if(msg["error"]) {
+ console.log('NAPAKA', msg["error"]);
+ stopStream();
+ return;
+ }
+ if(jsep) {
+ Janus.debug("Handling SDP as well...", jsep);
+ var stereo = (jsep.sdp.indexOf("stereo=1") !== -1);
+ // Offer from the plugin, let's answer
+ streaming.createAnswer({
+ jsep: jsep,
+ // We only specify data channels here, as this way in
+ // case they were offered we'll enable them. Since we
+ // don't mention audio or video tracks, we autoaccept them
+ // as recvonly (since we won't capture anything ourselves)
+ tracks: [{ type: 'data' }],
+ customizeSdp: function(jsep) {
+ if(stereo && jsep.sdp.indexOf("stereo=1") == -1) {
+ // Make sure that our offer contains stereo too
+ jsep.sdp = jsep.sdp.replace("useinbandfec=1", "useinbandfec=1;stereo=1");
+ }
+ },
+ success: function(jsep) {
+ Janus.debug("Got SDP!", jsep);
+ var body = { request: "start" };
+ streaming.send({ message: body, jsep: jsep });
+ },
+ error: function(error) {
+ Janus.error("WebRTC error:", error);
+ }
+ });
+ }
+ },
+ onremotetrack: function(track, mid, on, metadata) {
+ Janus.debug("Remote track (mid=" + mid + ") " + (on ? "added" : "removed") +
+ (metadata ? " (" + metadata.reason + ") ": "") + ":", track
+ );
+
+ var mstreamId = "mstream"+mid;
+ if(streamsList[selectedStream] && streamsList[selectedStream].legacy) {
+ mstreamId = "mstream0";
+ }
+
+ console.log('dodam?', on);
+ if(true) {
+ // If we're here, a new track was added
+ var stream = null;
+
+ // New video track: create a stream out of it
+ stream = new MediaStream([track]);
+ console.log('MOJ PRETOK!', stream, track);
+ remoteTracks[mid] = stream;
+ Janus.log("Created remote video stream:", stream);
+
+ var vidEl = document.querySelector('#videofeed');
+ var zaslonEl = document.querySelector('.zaslon');
+
+ /* bitrate in resolucija
+ if(!bitrateTimer[mid]) {
+ bitrateTimer[mid] = setInterval(function() {
+ // Display updated bitrate, if supported
+ var bitrate = streaming.getBitrate(mid);
+ console.log('bitrate:', bitrate);
+
+ // Check if the resolution changed too
+ var width = vidEl.videoWidth;
+ var height = vidEl.videoHeight;
+ if (width > 0 && height > 0) console.log('resolucija', width+'x'+height);
+ }, 1000);
+ }
+ */
+ console.log('dodajam pretok', vidEl, stream);
+ Janus.attachMediaStream(vidEl, stream);
+
+ vidEl.addEventListener('canplay', function () {
+ console.log('lahko predvajam!');
+ zaslonEl.classList.remove('cakam');
+ });
+
+ // Moramo kliknit za predvajanje :/
+ // predvajaj.style.display = 'block';
+ predvajaj.addEventListener('click', function () {
+ predvajaj.style.display = 'none';
+ vidEl.play();
+ });
+
+ vidEl.addEventListener('play', function () {
+ glavno.classList.add('predvajam');
+ predvajaj.style.display = 'none';
+ });
+
+ //vidEl.play();
+ }
+ },
+ ondataopen: function(data) {
+ Janus.log("The DataChannel is available!");
+ window.dataKanal = data;
+ },
+ ondata: function(data) {
+ Janus.debug("We got data from the DataChannel!", data);
+ console.log('DUBU DATA', data);
+ obdelajData(data);
+ },
+ oncleanup: function() {
+ Janus.log(" ::: Got a cleanup notification :::");
+ for(var i in bitrateTimer)
+ clearInterval(bitrateTimer[i]);
+ bitrateTimer = {};
+ remoteTracks = {};
+ dataMid = null;
+ }
+ });
+ },
+ error: function(error) {
+ Janus.error(error);
+ },
+ destroyed: function() {
+ window.location.reload();
+ }
+ });
+}});
+});
+
+function updateStreamsList() {
+ var body = { request: "list" };
+ Janus.debug("Sending message:", body);
+ streaming.send({ message: body, success: function(result) {
+ if(!result) {
+ console.log("Error: Got no response to our query for available streams");
+ return;
+ }
+ if(result["list"]) {
+ var list = result["list"];
+ if(list && Array.isArray(list)) {
+ list.sort(function(a, b) {
+ if(!a || a.id < (b ? b.id : 0))
+ return -1;
+ if(!b || b.id < (a ? a.id : 0))
+ return 1;
+ return 0;
+ });
+ }
+ Janus.log("Got a list of available streams:", list);
+ streamsList = {};
+ for(var mp in list) {
+ Janus.debug(" >> [" + list[mp]["id"] + "] " + list[mp]["description"] + " (" + list[mp]["type"] + ")");
+ // Check the nature of the available streams, and if there are some multistream ones
+ list[mp].legacy = true;
+ if(list[mp].media) {
+ var audios = 0, videos = 0;
+ for(var mi in list[mp].media) {
+ if(!list[mp].media[mi])
+ continue;
+ if(list[mp].media[mi].type === "audio")
+ audios++;
+ else if(list[mp].media[mi].type === "video")
+ videos++;
+ if(audios > 1 || videos > 1) {
+ list[mp].legacy = false;
+ break;
+ }
+ }
+ }
+ // Keep track of all the available streams
+ streamsList[list[mp]["id"]] = list[mp];
+ }
+
+ // Dajmo kar zacet
+ startStream();
+ }
+ }});
+}
+
+function getStreamInfo() {
+ // Send a request for more info on the mountpoint we subscribed to
+ var body = { request: "info", id: parseInt(selectedStream) || selectedStream };
+ streaming.send({ message: body, success: function(result) {
+ if(result && result.info && result.info.metadata) {
+ console.log('STREAM META', result.info.metadata);
+ }
+ }});
+}
+
+function startStream() {
+ Janus.log("Selected video id #" + selectedStream);
+ console.log('zacenjam', selectedStream, streamsList[selectedStream]);
+ if(!selectedStream || !streamsList[selectedStream]) {
+ console.log("Error: No stream selected to start");
+ return;
+ }
+
+ if(streamsList[selectedStream].legacy) {
+ for(mi in streamsList[selectedStream].media) {
+ // Add a new panel
+ var type = streamsList[selectedStream].media[mi].type;
+ if(type === "video") {
+ mid = streamsList[selectedStream].media[mi].mid;
+ break;
+ }
+ }
+ }
+ // Prepare the request to start streaming and send it
+ var body = { request: "watch", id: parseInt(selectedStream) || selectedStream };
+ streaming.send({ message: body });
+ getStreamInfo();
+}
+
+function stopStream() {
+ streaming.send({ message: body });
+ streaming.hangup();
+}
+
+function obdelajData(data) {
+ console.log('obdelam webrtc podatke', data);
+}
diff --git a/www/stil.css b/www/stil.css
index 898ad12..6c83ca7 100644
--- a/www/stil.css
+++ b/www/stil.css
@@ -37,7 +37,7 @@ h2 {
height: auto;
}
-video {
+#videofeed {
width: 100%;
height: auto;
box-sizing: border-box;