mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-11 21:58:35 +00:00
Merge pull request #976 from samthe13th/iframe-sandbox-v2
Refactor and redesign iframe.html
This commit is contained in:
commit
184d206ee0
326
iframe-examples.js
Normal file
326
iframe-examples.js
Normal file
@ -0,0 +1,326 @@
|
||||
/**
|
||||
* SANDBOX EXAMPLE CONFIG
|
||||
*
|
||||
* options: (number | boolean | string | null)[]
|
||||
* - OPTIONAL if using a user input; see "input" below
|
||||
* - List of values to test (passed into "result" function)
|
||||
* - An option button will be generated for each value in the list
|
||||
*
|
||||
* input: object
|
||||
* - OPTIONAL
|
||||
* - User input for testing (eg a range slider).
|
||||
* - Output of element onchange will be passed into RESULT function.
|
||||
*
|
||||
* labels: string[]
|
||||
* - OPTIONAL
|
||||
* - List of labels for option buttons (should be same length as options list).
|
||||
* - If no labels are provided, option buttons are labeled with their value
|
||||
*
|
||||
* result: (value: any) => object
|
||||
* - Function that returns a postMessage object
|
||||
* - Based on the value produced by an option button, or a user input
|
||||
*/
|
||||
|
||||
const IFRAME_API = {
|
||||
add: {
|
||||
options: [true],
|
||||
labels: ["Video with styles"],
|
||||
result: value => ({
|
||||
"target": "*",
|
||||
"add": value,
|
||||
"settings": { "style": "width:640px;height:360px;float:left;border:10px solid red;display:block;"}
|
||||
})
|
||||
},
|
||||
automixer: {
|
||||
options: [true, false],
|
||||
result: value => ({ "automixer": value })
|
||||
},
|
||||
bitrate: {
|
||||
options: [-1],
|
||||
labels: ["default (-1)"],
|
||||
input: {
|
||||
title: "bitrate",
|
||||
type: "range",
|
||||
min: 0,
|
||||
max: 6000,
|
||||
value: 3000
|
||||
},
|
||||
result: value => ({ "bitrate": value, "target": "*" })
|
||||
},
|
||||
camera: {
|
||||
options: [false, true, "toggle"],
|
||||
result: value => ({ "camera": value })
|
||||
},
|
||||
changeAudioDevice: { // change text of add camera button
|
||||
options: [1,2,3,4],
|
||||
result: value => ({ "changeAudioDevice": value })
|
||||
},
|
||||
changeVideoDevice: { // change text of add camera button
|
||||
options: [1,2,3,4],
|
||||
result: value => ({ "changeVideoDevice": value })
|
||||
},
|
||||
close: {
|
||||
options: [true],
|
||||
result: value => ({ "close": value })
|
||||
},
|
||||
getDetailedState: {
|
||||
options: [true],
|
||||
result: value => ({ "getDetailedState": value }),
|
||||
},
|
||||
getDeviceList: {
|
||||
options: [true],
|
||||
result: value => ({ "getDeviceList": value }),
|
||||
},
|
||||
getLoudness: {
|
||||
options: [false, true],
|
||||
result: value => ({ "getLoudness": value }),
|
||||
},
|
||||
getStreamIDs: {
|
||||
options: [true],
|
||||
result: value => ({ "getStreamIDs": value }),
|
||||
},
|
||||
keyframe: {
|
||||
options: [true],
|
||||
result: value => ({ "keyframe": value }),
|
||||
},
|
||||
mute: {
|
||||
options: [
|
||||
true,
|
||||
false,
|
||||
"toggle" // open to a better suggestion here.
|
||||
],
|
||||
result: value => ({ "mute": value }),
|
||||
},
|
||||
mic: {
|
||||
options: [true, false, "toggle"],
|
||||
result: value => ({ "mic": value }),
|
||||
},
|
||||
panning: {
|
||||
options: [0, 180, 90],
|
||||
input: {
|
||||
title: "panning",
|
||||
type: "range",
|
||||
min: 0,
|
||||
max: 180,
|
||||
value: 90
|
||||
},
|
||||
labels: ["Left (0)", "Right (180)", "Center (90)"],
|
||||
result: value => ({ "panning": value }),
|
||||
},
|
||||
previewWebcam: {
|
||||
options: ["previewWebcam"], // publishScreen
|
||||
result: value => ({ "function": value }),
|
||||
},
|
||||
record: {
|
||||
options: [true, false],
|
||||
result: value => ({ "record": value }),
|
||||
},
|
||||
reload: {
|
||||
options: [true],
|
||||
result: value => ({ "reload": value }),
|
||||
},
|
||||
remove: { // target can be a stream ID or * for all.
|
||||
options: [true],
|
||||
labels: ["Target video"],
|
||||
result: value => ({ "target": "*", "remove": value })
|
||||
},
|
||||
sendChat: {
|
||||
input: {
|
||||
type: "text",
|
||||
value: "Hello"
|
||||
},
|
||||
result: value => ({ "sendChat": value }),
|
||||
},
|
||||
sceneState: {
|
||||
options: [true, false],
|
||||
labels: ["ENABLE TALLY LIGHT (true)", "STOP TALLY LIGHT (false)"],
|
||||
result: value => ({ "sceneState": value })
|
||||
},
|
||||
style: {
|
||||
options: ["#main { zoom: 0.5;} video {float: left; margin: 0; padding: 0; } #info {display:none;}"],
|
||||
labels: ["Insert Style Sheet"],
|
||||
result: value => ({ "style": value }),
|
||||
},
|
||||
volume: {
|
||||
input: {
|
||||
title: "volume",
|
||||
type: "range",
|
||||
min: 0,
|
||||
max: 200,
|
||||
value: 100
|
||||
},
|
||||
result: value => ({ "volume": value }),
|
||||
},
|
||||
["function: Eval"]: {
|
||||
options: ["eval"], // publishScreen
|
||||
result: value => ({ "function": value, "value": 'alert(\"DANGERUS\")' })
|
||||
},
|
||||
["function: Change html"]: {
|
||||
options: ["changeHTML"], // change text of add camera button
|
||||
result: value => ({ "function": value, "target": "add_camera", "value": "NEW CAMERA TEXT" })
|
||||
}
|
||||
}
|
||||
|
||||
const COMPANION_API = { // list available commands to console
|
||||
bitrate: {
|
||||
input: {
|
||||
title: "bitrate",
|
||||
type: "range",
|
||||
min: 0,
|
||||
max: 6000,
|
||||
value: 3000
|
||||
},
|
||||
result: value => ({ target: null, action: "bitrate", value })
|
||||
},
|
||||
camera: {
|
||||
options: [false, true, "toggle"],
|
||||
result: value => ({ target: null, action: "camera", value })
|
||||
},
|
||||
forceKeyframe: {
|
||||
options: [null],
|
||||
labels: ["Rainbow puke fix"],
|
||||
result: value => ({ target: null, action: "forceKeyframe", value }),
|
||||
},
|
||||
getDetails: {
|
||||
options: [null],
|
||||
result: value => ({ target: null, action: "getDetails", value })
|
||||
},
|
||||
group: {
|
||||
options: [1,2,3,4,5,6,7,8],
|
||||
result: value => ({ target: null, action: "group", value })
|
||||
},
|
||||
hangup: {
|
||||
options: [null],
|
||||
result: value => ({ target: null, action: "hangup", value })
|
||||
},
|
||||
mic: {
|
||||
options: [false, true, "toggle"],
|
||||
result: value => ({ target: null, action: "mic", value })
|
||||
},
|
||||
panning: {
|
||||
options: [0, 180, 90],
|
||||
input: {
|
||||
title: "panning",
|
||||
type: "range",
|
||||
min: 0,
|
||||
max: 180,
|
||||
value: 90
|
||||
},
|
||||
labels: ["Left (0)", "Right (180)", "Center (90)"],
|
||||
result: value => ({ target: null, action: "panning", value })
|
||||
},
|
||||
record: {
|
||||
options: [false, true, "toggle"],
|
||||
result: value => ({ target: null, action: "record", value })
|
||||
},
|
||||
reload: {
|
||||
options: [null],
|
||||
result: value => ({ target: null, action: "reload", value })
|
||||
},
|
||||
sendChat: {
|
||||
input: {
|
||||
type: "text",
|
||||
value: "Hello"
|
||||
},
|
||||
result: value => ({ target: null, action: "sendChat", value }),
|
||||
},
|
||||
speaker: { // "speaker" also works in the same way
|
||||
options: [false, true, "toggle"],
|
||||
result: value => ({ target: null, action: "speaker", value }),
|
||||
},
|
||||
togglehand: {
|
||||
options: [null],
|
||||
result: value => ({ target: null, action: "togglehand", value }),
|
||||
},
|
||||
togglescreenshare: {
|
||||
options: [null],
|
||||
result: value => ({ target: null, action: "togglescreenshare", value }),
|
||||
},
|
||||
volume: {
|
||||
input: {
|
||||
title: "volume",
|
||||
type: "range",
|
||||
min: 0,
|
||||
max: 200,
|
||||
value: 100
|
||||
},
|
||||
result: value => ({ target: null, "action": "volume", value }),
|
||||
},
|
||||
}
|
||||
|
||||
function guestTargetedAPI(target) {
|
||||
return {
|
||||
addScene: {
|
||||
options: [null,1,2,3,4,5,6,7,8],
|
||||
input: {
|
||||
type: "text",
|
||||
value: "scene321"
|
||||
},
|
||||
result: value => ({ "action": "addScene", target, value })
|
||||
},
|
||||
display: {
|
||||
options: [null],
|
||||
result: value => ({ "action": "display", target, value })
|
||||
},
|
||||
forward: {
|
||||
options: [null],
|
||||
input: {
|
||||
type: "text",
|
||||
value: "room321"
|
||||
},
|
||||
result: value => ({ "action": "forward", target, value })
|
||||
},
|
||||
forceKeyframe: {
|
||||
options: [null],
|
||||
labels: ["Rainbow puke fix"],
|
||||
result: value => ({ "action": "forceKeyframe", target, value })
|
||||
},
|
||||
hangup: {
|
||||
options: [null],
|
||||
result: value => ({ "action": "hangup", target, value })
|
||||
},
|
||||
group: {
|
||||
options: [0,1,2,3,4,5,6,7,8],
|
||||
input: {
|
||||
type: "text",
|
||||
value: "group321"
|
||||
},
|
||||
result: value => ({ "action": "group", target, value })
|
||||
},
|
||||
soloChat: {
|
||||
options: [null],
|
||||
result: value => ({ "action": "soloChat", target, value })
|
||||
},
|
||||
soloVideo: {
|
||||
options: [null],
|
||||
result: value => ({ "action": "soloVideo", target, value })
|
||||
},
|
||||
speaker: {
|
||||
options: [null],
|
||||
labels: ["Remote speaker"],
|
||||
result: value =>({ "action": "speaker", target, value })
|
||||
},
|
||||
mic: {
|
||||
options: [null],
|
||||
result: value =>({ "action": "mic", target, value })
|
||||
},
|
||||
muteScene: {
|
||||
options: [null,1,2,3,4,5,6,7,8],
|
||||
input: {
|
||||
type: "text",
|
||||
value: "scene321"
|
||||
},
|
||||
result: value => ({ "action": "muteScene", target, value })
|
||||
},
|
||||
volume: {
|
||||
input: {
|
||||
title: "volume",
|
||||
type: "range",
|
||||
min: 0,
|
||||
max: 200,
|
||||
value: 100
|
||||
},
|
||||
result: value => ({ "action": "volume", target, value }),
|
||||
},
|
||||
}
|
||||
}
|
||||
200
iframe.css
Normal file
200
iframe.css
Normal file
@ -0,0 +1,200 @@
|
||||
body {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
background-color: #e1e8fc;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 0;
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 5px;
|
||||
background: white;
|
||||
border: solid;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
button:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
video {
|
||||
max-width: 300px;
|
||||
max-height: 100px;
|
||||
}
|
||||
|
||||
#viewlink {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
#container {
|
||||
display: flex;
|
||||
padding: 0;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.api-section {
|
||||
padding: 10px;
|
||||
border-bottom: solid 1px;
|
||||
}
|
||||
|
||||
.api-section > h4:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.api-section-header {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border-bottom: solid 1px;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.custom-post {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.custom-post > * {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.custom-post > button {
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
padding: 0 20px;
|
||||
font-size: 16px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.custom-post-input {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: solid 5px #4d66a8;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.controls {
|
||||
overflow: auto;
|
||||
background: white;
|
||||
width: 350px;
|
||||
flex-shrink: 0;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.example-body {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 700px;
|
||||
}
|
||||
|
||||
.example-header {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
background: #4d66a8;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.example-header > button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.iframe-example {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 20px;
|
||||
border: solid #4d66a8 2px;
|
||||
}
|
||||
|
||||
.main-log {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
flex-shrink: 0;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
background: #0b0e15;
|
||||
color: white;
|
||||
border-top: solid 1px #6e6e6e;
|
||||
font-family: monospace;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.output-container {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.post-log {
|
||||
background: #273047;
|
||||
padding: 4px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.sensors-log {
|
||||
padding: 10px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.stream-data-logs {
|
||||
height: 100%;
|
||||
background: black;
|
||||
color: white;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.target-guest {
|
||||
padding: 10px;
|
||||
border-bottom: solid 1px;
|
||||
}
|
||||
|
||||
.target-guest-inputs {
|
||||
margin-top: 5px;
|
||||
}
|
||||
1169
iframe.html
1169
iframe.html
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user