Compare commits
10 Commits
050f887398
...
4d4591fb2d
Author | SHA1 | Date | |
---|---|---|---|
4d4591fb2d | |||
e5b57dd3d7 | |||
d5c8fcd055 | |||
980d6822d0 | |||
68b20a8b4f | |||
c5fb07f6da | |||
c4f1e4d8c0 | |||
d62722ce53 | |||
3a3e008e90 | |||
74e8731fa4 |
14
README.md
14
README.md
@ -1,5 +1,13 @@
|
||||
# LOLED
|
||||
|
||||
```
|
||||
apt install xorg fluxbox lightdm
|
||||
```
|
||||
Outil de projection sur l'ecran led du LOL
|
||||
|
||||
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.
|
10
loled.js
10
loled.js
@ -82,12 +82,20 @@ app.use((ctx, next) => {
|
||||
ctx.response.headers.append("Access-Control-Allow-Headers", "*")
|
||||
|
||||
if(ctx.request.method == "OPTION"){
|
||||
ctx.response.status = 200
|
||||
ctx.response.status = 204
|
||||
} else {
|
||||
return next()
|
||||
}
|
||||
})
|
||||
|
||||
app.use((ctx, next) => {
|
||||
if(ctx.request.url.pathname.startsWith("/_loled")){
|
||||
ctx.response.headers.append("Cache-Control", "no-store")
|
||||
}
|
||||
|
||||
return next()
|
||||
})
|
||||
|
||||
// Static
|
||||
app.use(async (ctx, next) => {
|
||||
if(ctx.request.url.pathname.startsWith("/_loled"))
|
||||
|
@ -10,7 +10,7 @@
|
||||
<p>To send canvas of the page to LOLED click the following link :
|
||||
<a id="link" href="">LOLED that canvas !</a>
|
||||
</p>
|
||||
<p>You can also drag this link in your bookmarks to call it on any page with a canvas</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>
|
||||
<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);})()`
|
||||
</script>
|
||||
|
@ -90,6 +90,6 @@ async function getRegistration(name){
|
||||
const args = new URLSearchParams(location.search);
|
||||
init(
|
||||
args.get("name"),
|
||||
parseInt(args.get("width")),
|
||||
parseInt(args.get("height"))
|
||||
parseInt(args.get("width") || window.innerWidth),
|
||||
parseInt(args.get("height") || window.innerHeight)
|
||||
)
|
@ -2,9 +2,10 @@
|
||||
const globalConnnection = Symbol("grab-canvas-connection")
|
||||
|
||||
const currentScriptSrc = document.currentScript.src;
|
||||
const canvas = document.querySelector("canvas");
|
||||
const sourceElt = document.querySelector("canvas,video");
|
||||
console.log("Grabbing", sourceElt)
|
||||
|
||||
if(!canvas){
|
||||
if(!sourceElt){
|
||||
console.error("No canvas found on this page")
|
||||
}
|
||||
|
||||
@ -22,10 +23,38 @@
|
||||
const allCandidatesCollected = new Promise(res =>
|
||||
conn.addEventListener("icecandidate", e => e.candidate == null && res() ))
|
||||
|
||||
const canvasStream = canvas.captureStream()
|
||||
let captureFn = sourceElt.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()
|
||||
if(canvasStreamTracks.length > 0){
|
||||
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();
|
||||
|
Loading…
Reference in New Issue
Block a user