Compare commits

..

No commits in common. "4d4591fb2de4e85de6a6d1a12f28d39e84786c1b" and "050f887398c262e2c0fd306b97609b5ab3561ed6" have entirely different histories.

5 changed files with 10 additions and 55 deletions

View File

@ -1,13 +1,5 @@
# LOLED # LOLED
Outil de projection sur l'ecran led du LOL ```
apt install xorg fluxbox lightdm
L'ecran lED du LOL est controlle par une carte PCI qui prend une portion de l'ecran pour en mapper chaque pixel sur l'ecran LED. ```
Avec LOLED : un serveur (`loled.js`) execute avec [Deno](https://deno.com/) et mets a disposition les elements suivants :
* Une page `/display` qui doit etre ouverte en plein ecran sur un navigateur interne
* Une page d'index `/` qui donne quelques details et instructions sur comment utiliser l'outil sur le WEB
* Un script `/js/grab-canvas.js` qui peut etre execute sur n'importe quel page du web dispose d'un element video ou canvas, le flux video du premier element trouve sera alors envoye a l'ecran
Techniquement, le systeme repose sur une connexion WebRTC et utilise le serveur comme serveur de signalisation. Sur la machine assocee a l'ecran LED nous avons demarre une session fluxbox avec LightDM. Flubox demarre un firefox automatquement qui se connecte au serveur en tant qu'affichage.

View File

@ -82,20 +82,12 @@ app.use((ctx, next) => {
ctx.response.headers.append("Access-Control-Allow-Headers", "*") ctx.response.headers.append("Access-Control-Allow-Headers", "*")
if(ctx.request.method == "OPTION"){ if(ctx.request.method == "OPTION"){
ctx.response.status = 204 ctx.response.status = 200
} else { } else {
return next() return next()
} }
}) })
app.use((ctx, next) => {
if(ctx.request.url.pathname.startsWith("/_loled")){
ctx.response.headers.append("Cache-Control", "no-store")
}
return next()
})
// Static // Static
app.use(async (ctx, next) => { app.use(async (ctx, next) => {
if(ctx.request.url.pathname.startsWith("/_loled")) if(ctx.request.url.pathname.startsWith("/_loled"))

View File

@ -10,7 +10,7 @@
<p>To send canvas of the page to LOLED click the following link : <p>To send canvas of the page to LOLED click the following link :
<a id="link" href="">LOLED that canvas !</a> <a id="link" href="">LOLED that canvas !</a>
</p> </p>
<p>You can also drag this link in your bookmarks to call it on any page with a canvas. Like <a href="https://hydra.ojack.xyz/">Hydra</a> or <a href="https://topos.raphaelforment.fr/">Topos</a>.</p> <p>You can also drag this link in your bookmarks to call it on any page with a canvas</p>
<script> <script>
document.getElementById("link").href = `javascript:(function(){let s = document.createElement('script');s.src = '${new URL("/js/grab-canvas.js", document.documentElement.baseURI).toString()}';document.body.appendChild(s);})()` document.getElementById("link").href = `javascript:(function(){let s = document.createElement('script');s.src = '${new URL("/js/grab-canvas.js", document.documentElement.baseURI).toString()}';document.body.appendChild(s);})()`
</script> </script>

View File

@ -90,6 +90,6 @@ async function getRegistration(name){
const args = new URLSearchParams(location.search); const args = new URLSearchParams(location.search);
init( init(
args.get("name"), args.get("name"),
parseInt(args.get("width") || window.innerWidth), parseInt(args.get("width")),
parseInt(args.get("height") || window.innerHeight) parseInt(args.get("height"))
) )

View File

@ -2,10 +2,9 @@
const globalConnnection = Symbol("grab-canvas-connection") const globalConnnection = Symbol("grab-canvas-connection")
const currentScriptSrc = document.currentScript.src; const currentScriptSrc = document.currentScript.src;
const sourceElt = document.querySelector("canvas,video"); const canvas = document.querySelector("canvas");
console.log("Grabbing", sourceElt)
if(!sourceElt){ if(!canvas){
console.error("No canvas found on this page") console.error("No canvas found on this page")
} }
@ -23,38 +22,10 @@
const allCandidatesCollected = new Promise(res => const allCandidatesCollected = new Promise(res =>
conn.addEventListener("icecandidate", e => e.candidate == null && res() )) conn.addEventListener("icecandidate", e => e.candidate == null && res() ))
let captureFn = sourceElt.captureStream; const canvasStream = canvas.captureStream()
if(!captureFn){
captureFn = sourceElt.mozCaptureStream;
}
if(sourceElt instanceof HTMLCanvasElement){
captureFn = sourceElt.captureStream.bind(sourceElt)
} else {
if(sourceElt.mozCaptureStream){
captureFn = sourceElt.mozCaptureStream.bind(sourceElt)
} else {
captureFn = sourceElt.captureStream.bind(sourceElt)
}
}
const canvasStream = captureFn()
const canvasStreamTracks = canvasStream.getVideoTracks() const canvasStreamTracks = canvasStream.getVideoTracks()
if(canvasStreamTracks.length > 0){ if(canvasStreamTracks.length > 0){
conn.addTrack(canvasStreamTracks[0], canvasStream) conn.addTrack(canvasStreamTracks[0], canvasStream)
} else {
throw new Error("Element don't habe video track")
}
try {
const AudioContext = window.AudioContext || window.webkitAudioContext;
if(AudioContext){
const audioContext = new AudioContext();
audioContext.createMediaStreamSource(canvasStream)
.connect(audioContext.destination)
}
} catch(e){
console.warn(e)
} }
const offer = await conn.createOffer(); const offer = await conn.createOffer();