MWSE/public/studio/InputDevices.js

398 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import DWindow from "./window.js";
import { AddCell, FilterCell, memory, RemoveCell } from "./sdb.js";
export const InputDevicesWindow = new class InputDevicesWindow extends DWindow{
constructor(){
super();
this.initContent();
this.headtext.text("Giriş Aygıtları");
this.hide();
this.panel.css("min-width","640px");
this.panel.css("min-height","250px");
this.panel.css("width","max-content");
this.initEvent();
}
/**
* @type {JQuery<HTMLElement>}
*/
table = null;
initContent(){
this.table = $(`
<table class="table table-sm table-bordered table-striped text-nowrap">
<thead>
<tr>
<th>Cihaz Türü</th>
<th>Sağlanan Kanallar</th>
<th>Akış ID</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<button class="btn btn-success w-100 newdevice">
Yeni Giriş Cihazı Ekle
</button>
</td>
</tr>
</tfoot>
</table>
`);
this.updateDevices();
this.content.append(this.table);
}
initEvent(){
this.content.find(".newdevice").on('click', this.generateDevice.bind(this));
this.addEventListener("close",()=>{
this.hide();
})
}
updateDevices(){
let tbody = this.table.find("tbody");
tbody.text('');
for (const cell of FilterCell("rawstream", () => true))
{
let tr = $(`
<tr class="text-nowrap">
<td>${cell.source}</td>
<td>${cell.kind}</td>
<td>${cell.payload.id}</td>
<td>
<button class="btn btn-outline-primary action-view">Görüntüle</button>
<button class="btn btn-outline-danger action-close">Kapat</button>
</td>
</tr>
`);
tr.attr("data-declare", cell.payload.id);
cell.addEventListener("stop",() => tr.remove());
tbody.append(tr);
}
tbody.find(".action-view").on('click', e => this.viewSource($(e.target)));
tbody.find(".action-close").on('click', e => this.closeSource($(e.target)));
}
closeSource(btn){
let streamid = btn.closest("tr").attr("data-declare");
for (const brain of FilterCell("rawstream",e => e.payload.id == streamid)) {
brain.stop();
}
}
viewSource(btn){
let streamid = btn.closest("tr").attr("data-declare");
/**
* @type {MediaStream}
*/
let p = null;
for (const rawstream of FilterCell("rawstream",e => e.payload.id == streamid)) {
p = rawstream.payload;
}
let modal = new ViewSourceDialog(p.getTracks()[0]);
modal.enableDialog(this);
modal.bringToFront();
}
generateDevice(){
let modal = new AddDeviceDialog();
modal.enableDialog(this);
modal.bringToFront();
modal.addEventListener("stream:added",()=>{
this.updateDevices();
});
}
}
class StreamRecord extends EventTarget {
lockedby = 0;
stop(){
this.payload.getTracks().forEach(e => e.stop());
this.dispatchEvent(new Event("stop"));
}
isLocked(){
return this.lockedby != 0;
}
lock(){
this.lockedby++;
}
unlock(){
this.lockedby--;
}
}
class AddDeviceDialog extends DWindow {
constructor(){
super();
this.initContent();
this.headtext.text("Aygıt Ekleme Sihirbazı");
this.addEventListener('close',()=>{
this.disableDialog();
this.exit();
})
}
initContent(){
let table = $(`
<div style="display:flex;flex-direction:column;gap:5px">
<button class="btn btn-success w-100 action-sdcam">
SD Kamara Ekle
</button>
<button class="btn btn-success w-100 action-hdcam">
HD Kamara Ekle
</button>
<button class="btn btn-success w-100 action-mic">
Mikrofon Ekle
</button>
<button class="btn btn-success w-100 action-displaycam">
Ekran Görüntüsü Ekle
</button>
</div>
`);
table.find(".action-sdcam").on("click",this.sdcam.bind(this));
table.find(".action-hdcam").on("click",this.hdcam.bind(this));
table.find(".action-mic").on("click",this.mic.bind(this));
table.find(".action-displaycam").on("click",this.displaycam.bind(this));
this.content.append(table);
}
async sdcam(){
let stream = await navigator.mediaDevices.getUserMedia({
video: {
advanced: [
{ width: { exact: 640 } },
{ width: { exact: 320 } },
{ width: { exact: 240 } }
],
facingMode: "user"
}
});
AddCell("rawstream", new class extends StreamRecord {
source = "Kamera";
kind = "Görüntü";
payload = stream;
constructor(){
super();
this.onEnded(() => {
this.dispatchEvent(new Event("stop"));
})
this.addEventListener("stop",() => {
RemoveCell("rawstream",cell => {
return cell.payload.id == stream.id
})
})
}
onEnded(event){
/** @type {MediaStreamTrack} */
let track;
stream.getVideoTracks().forEach(e => track = e);
if(track)
{
track.addEventListener("ended",event);
}
}
});
this.dispatchEvent(new Event("stream:added"));
this.disableDialog();
this.exit();
}
async hdcam(){
let stream = await navigator.mediaDevices.getUserMedia({
video: {
advanced: [
{ width: { exact: 1920 } },
{ width: { exact: 1600 } },
{ width: { exact: 1366 } },
{ width: { exact: 1280 } },
{ width: { exact: 1024 } },
{ width: { exact: 900 } },
{ width: { exact: 800 } },
{ width: { exact: 640 } },
{ width: { exact: 320 } },
{ width: { exact: 240 } }
],
facingMode: "user"
}
});
AddCell("rawstream", new class extends StreamRecord {
source = "Kamera";
kind = "Görüntü";
payload = stream;
constructor(){
super();
this.onEnded(() => {
this.dispatchEvent(new Event("stop"));
})
this.addEventListener("stop",() => {
RemoveCell("rawstream",cell => {
return cell.payload.id == stream.id
})
})
}
onEnded(event){
/** @type {MediaStreamTrack} */
let track;
stream.getVideoTracks().forEach(e => track = e);
if(track)
{
track.addEventListener("ended",event);
}
}
});
this.dispatchEvent(new Event("stream:added"));
this.disableDialog();
this.exit();
}
async mic(){
let stream = await navigator.mediaDevices.getUserMedia({
audio: true
});
AddCell("rawstream", new class extends StreamRecord {
source = "Kamera";
kind = "Ses";
payload = stream;
constructor(){
super();
this.onEnded(() => {
this.dispatchEvent(new Event("stop"));
})
this.addEventListener("stop",() => {
RemoveCell("rawstream",cell => {
return cell.payload.id == stream.id
})
})
}
onEnded(event){
/** @type {MediaStreamTrack} */
let track;
stream.getAudioTracks().forEach(e => track = e);
if(track)
{
track.addEventListener("ended",event);
}
}
});
this.dispatchEvent(new Event("stream:added"));
this.disableDialog();
this.exit();
}
async displaycam(){
let stream = await navigator.mediaDevices.getDisplayMedia({
video: true
});
AddCell("rawstream", new class extends StreamRecord{
source = "Ekran";
kind = "Görüntü";
payload = stream;
constructor(){
super();
this.onEnded(() => {
this.dispatchEvent(new Event("stop"));
})
this.addEventListener("stop",() => {
RemoveCell("rawstream",cell => {
return cell.payload.id == stream.id
})
})
}
onEnded(event){
/** @type {MediaStreamTrack} */
let track;
stream.getTracks().forEach(e => track = e);
if(track)
{
track.addEventListener("ended",event);
}
}
});
this.dispatchEvent(new Event("stream:added"));
this.disableDialog();
this.exit();
}
}
class ViewSourceDialog extends DWindow {
/**
* @type {MediaStreamTrack}
*/
track = null;
extra = {};
constructor(track){
super();
this.headtext.text("Giriş Kaynağı Görüntüleme");
this.addEventListener('close',()=>{
this.disableDialog();
this.exit();
})
this.track = track;
this.initContent();
}
initContent(){
if(this.track.kind == "video")
{
this.initVideoContent();
}else{
this.initAudioContent();
}
this.table = $(`<table class="table">
<tbody>
<tr>
<td>Track ID</td>
<td>${this.track.id}</td>
</tr>
<tr>
<td>Data Type</td>
<td>${this.track.kind}</td>
</tr>
<tr>
<td>Status</td>
<td>${this.track.enabled ? "Active" : "Passive"}</td>
</tr>
<tr>
<td>Track Label</td>
<td>${this.track.label}</td>
</tr>
</tbody>
</table>`);
this.content.append(this.table);
}
initVideoContent(){
let player = $(`<video
style="height: 450px"
controls
/>`);
let stream = new MediaStream();
stream.addTrack(this.track);
player.on('canplay', e => e.target.play());
player.get(0).srcObject = stream;
this.content.append(player);
player.on('play', e => {
this.table.find("tbody").append(`
<tr>
<td>Video Width</td>
<td>${e.target.videoWidth}px</td>
</tr>
`);
this.table.find("tbody").append(`
<tr>
<td>Video Height</td>
<td>${e.target.videoHeight}px</td>
</tr>
`);
});
}
initAudioContent(){
let player = $(`<audio
style="width: 500px"
controls
/>`);
let stream = new MediaStream();
stream.addTrack(this.track);
player.get(0).srcObject = stream;
player.on('canplay', e => e.target.play());
this.content.append(player);
}
}