Skip to content

Commit

Permalink
📺 NDI output send new frame when reconnected
Browse files Browse the repository at this point in the history
- Per video volume
- Fixed per audio volume not affecting audio meter
- Version update
  • Loading branch information
vassbo committed Dec 13, 2024
1 parent f0a150c commit 776f465
Show file tree
Hide file tree
Showing 12 changed files with 59 additions and 103 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "freeshow",
"version": "1.3.3-beta.1",
"version": "1.3.3-beta.2",
"private": true,
"main": "build/electron/index.js",
"description": "Show song lyrics and more for free!",
Expand Down
91 changes: 11 additions & 80 deletions public/global.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* custom CMG Sans */
@font-face {
font-family: "CMGSans";
src: url("./fonts/CMGSans-Regular.ttf");
Expand Down Expand Up @@ -39,20 +40,26 @@

--hover: rgb(255 255 255 / 0.05);
--focus: rgb(255 255 255 / 0.1);
/* --active: rgb(230 52 156 / .8); */

/* --font-family: sans-serif; */
/* https://css-tricks.com/snippets/css/system-font-stack/ */
/* --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; */
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
--font-size: 1em;

--border-radius: 0;

/* --navigation-width: 18vw; */
--navigation-width: 290px;
}

* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;

outline-offset: -4px;
outline-color: var(--secondary);
}

html,
body {
position: relative;
Expand All @@ -63,9 +70,6 @@ body {
body {
display: flex;
flex-direction: column;
/* background-color: #292c36;
background-color: var(--primary); */
color: #f0f0ff;
color: var(--text);
box-sizing: border-box;
transition: background-color 0.5s;
Expand Down Expand Up @@ -122,76 +126,3 @@ p {
overflow: hidden;
white-space: nowrap;
}

* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;

outline-offset: -4px;
outline-color: var(--secondary);
}

/* button {
font-family: sans-serif;
font-family: system-ui;
} */

/* body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
-webkit-padding: 0.4em 0;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
} */
2 changes: 1 addition & 1 deletion src/electron/capture/helpers/CaptureTransmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class CaptureTransmitter {
// WIP one global capture (on the highest frame rate) instead of multiple per frame rate - but using multipe at once is probably an edge case
static startChannel(captureId: string, key: string) {
const combinedKey = `${captureId}-${key}`
const interval = 1000 / OutputHelper.getOutput(captureId)?.captureOptions?.framerates?.[key] || 30
const interval = 1000 / (OutputHelper.getOutput(captureId)?.captureOptions?.framerates?.[key] || 30)
// console.log("START CHANNEL:", key, interval)

if (this.channels[combinedKey]?.timer) {
Expand Down
12 changes: 10 additions & 2 deletions src/electron/ndi/NdiSender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import os from "os"
import { toApp } from ".."
import { CaptureHelper } from "../capture/CaptureHelper"
import util from "./vingester-util"

// WIP - NDI issue on Linux: libndi.so.5: No such file or dialog
import { CaptureTransmitter } from "../capture/helpers/CaptureTransmitter"

// Resources:
// https://www.npmjs.com/package/grandiose-mac
Expand Down Expand Up @@ -63,6 +62,15 @@ export class NdiSender {
CaptureHelper.updateFramerate(id)

this.NDI[id].previousStatus = newStatus

if (this.NDI[id].status === "connected") {
Object.keys(CaptureTransmitter.channels).forEach((key) => {
if (key.includes("ndi")) {
// force an instant check / output refresh when reconnected
CaptureTransmitter.channels[key].lastCheck = 999
}
})
}
}
}, 1000)
}
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/components/edit/EditTools.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import Tabs from "../main/Tabs.svelte"
import Center from "../system/Center.svelte"
import { getBoxStyle, getFilterStyle, getItemStyle, getSlideStyle, setBoxStyle, setFilterStyle, setItemStyle, setSlideStyle } from "./scripts/itemClipboard"
import { DEFAULT_ITEM_STYLE } from "./scripts/itemHelpers"
import { addStyleString } from "./scripts/textStyle"
import BoxStyle from "./tools/BoxStyle.svelte"
import ItemStyle from "./tools/ItemStyle.svelte"
Expand Down Expand Up @@ -168,7 +169,7 @@
if (active === "item") {
history({
id: "setStyle",
newData: { style: { key: "style", values: ["top:120px;left:50px;height:840px;width:1820px;"] } },
newData: { style: { key: "style", values: [DEFAULT_ITEM_STYLE] } },
location: { page: "edit", show: $activeShow!, slide, items: $activeEdit.items },
})
return
Expand Down
9 changes: 5 additions & 4 deletions src/frontend/components/edit/MediaTools.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@
let videoDuration = video?.duration || 0
if (!videoDuration) return
edits.video[2].value = currentMedia?.toTime || videoDuration
edits.video[1].values = { max: videoDuration }
edits.video[3].value = currentMedia?.toTime || videoDuration
edits.video[2].values = { max: videoDuration }
edits.video[3].values = { max: videoDuration }
}
}
Expand All @@ -60,8 +60,9 @@
edits.default[2].value = currentMedia.flippedY || false
if (edits.video) {
edits.video[0].value = currentMedia.speed || "1"
edits.video[1].value = currentMedia.fromTime || 0
edits.video[2].value = currentMedia.toTime || edits.video[2].value
edits.video[1].value = currentMedia.volume ?? 100
edits.video[2].value = currentMedia.fromTime || 0
edits.video[3].value = currentMedia.toTime || edits.video[3].value
}
// update filters
Expand Down
7 changes: 7 additions & 0 deletions src/frontend/components/edit/values/media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ export const videoEdit = [
],
},
},
{
name: "media.volume",
id: "volume",
input: "number",
value: 100,
values: { max: 100 },
},
{
name: "inputs.start",
id: "fromTime",
Expand Down
12 changes: 9 additions & 3 deletions src/frontend/components/helpers/audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ export async function playAudio({ path, name = "", audio = null, stream = null }
})

let localVolume: number = get(volume) * (get(media)[path]?.volume || 1)
if (analyser.gainNode) analyser.gainNode.gain.value = localVolume * (get(gain) || 1)
else audio.volume = localVolume
if (analyser.gainNode) {
analyser.gainNode.gain.value = localVolume * (get(gain) || 1)
if (get(special).preFaderVolumeMeter) audio.volume = 1
else audio.volume = localVolume
} else audio.volume = localVolume

let waitToPlay = 0
if (audioPlaying && crossfade) {
Expand Down Expand Up @@ -171,6 +174,9 @@ export function updateVolume(value: number | undefined | "local", changeGain: bo
if (a[id].analyser.gainNode) {
let gainedValue = localVolume * (get(gain) || 1)
a[id].analyser.gainNode.gain.value = gainedValue

if (get(special).preFaderVolumeMeter) a[id].audio.volume = 1
else a[id].audio.volume = localVolume
} else a[id].audio.volume = localVolume
})

Expand Down Expand Up @@ -516,7 +522,7 @@ function getPlayingVideos() {

videos.map((a) => {
// set volume (video in output window)
let newVolume = get(volume)
let newVolume = get(volume) * ((get(media)[a.id]?.volume ?? 100) / 100)
if (a.analyser.gainNode) {
let gainedValue = newVolume * (get(gain) || 1)
a.analyser.gainNode.gain.value = gainedValue
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/components/main/popups/Unsaved.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
{:else}
<CombinedInput>
<Button style="width: 100%;" on:click={closeApp} dark center>
<div style="display: inline;opacity: 0.7;display: flex;align-items: center;"><T id="popup.quit" /></div>
<div style="display: inline;opacity: 0.7;display: flex;align-items: center;border: none;"><T id="popup.quit" /></div>
<span>Q</span>
</Button>
</CombinedInput>
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/components/output/layers/BackgroundMedia.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { OUTPUT } from "../../../../types/Channels"
import type { MediaStyle } from "../../../../types/Main"
import type { OutBackground, Transition } from "../../../../types/Show"
import { allOutputs, audioChannels, outputs, playingVideos, special, videosData, videosTime } from "../../../stores"
import { allOutputs, audioChannels, media, outputs, playingVideos, special, videosData, videosTime, volume } from "../../../stores"
import { destroy, receive, send } from "../../../utils/request"
import BmdStream from "../../drawer/live/BMDStream.svelte"
import NdiStream from "../../drawer/live/NDIStream.svelte"
Expand Down Expand Up @@ -163,7 +163,7 @@
// FADE OUT AUDIO
$: if (fadingOut && !videoData.muted) fadeoutVideo()
$: if (!fadingOut && !videoData.muted && id) setVolume(1)
$: if (!fadingOut && !videoData.muted && id) setVolume($volume * (($media[id]?.volume ?? 100) / 100))
const speed = 0.01
const margin = 0.9 // video should fade to 0 before clearing
function fadeoutVideo() {
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/components/show/formatTextEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { history } from "../helpers/history"
import { isEmptyOrSpecial } from "../helpers/output"
import { getGlobalGroup } from "../helpers/show"
import { _show } from "../helpers/shows"
import { DEFAULT_ITEM_STYLE } from "../edit/scripts/itemHelpers"

export function formatText(text: string, showId: string = "") {
if (!showId) showId = get(activeShow)?.id || ""
Expand Down Expand Up @@ -283,7 +284,7 @@ function getSlide(slideText): Slide {
return slide
}

export const defaultItem: Item = { type: "text", lines: [], style: "top:120px;left:50px;height:840px;width:1820px;" }
export const defaultItem: Item = { type: "text", lines: [], style: DEFAULT_ITEM_STYLE }
const textboxRegex = /\[#(\d+)(?::([^\]]+))?\]/
export function linesToTextboxes(slideLines: string[]) {
let items: Item[] = []
Expand Down
15 changes: 8 additions & 7 deletions src/frontend/utils/createData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { setShow } from "../components/helpers/setShow"
import { audioFolders, dictionary, folders, mediaFolders, overlays, projects, remotePassword, shows, templates } from "../stores"
import { stageShows, templateCategories } from "./../stores"
import { save } from "./save"
import { DEFAULT_ITEM_STYLE } from "../components/edit/scripts/itemHelpers"

export function createData(paths: any) {
if (!get(shows).default) {
Expand Down Expand Up @@ -215,7 +216,7 @@ export function setExampleTemplates() {
category: "song",
items: [
{
style: "top:120px;left:50px;height:840px;width:1820px;",
style: DEFAULT_ITEM_STYLE,
align: "",
lines: [{ align: "", text: [{ value: get(dictionary).example?.big || "Big", style: "font-size: 120px;" }] }],
},
Expand All @@ -227,7 +228,7 @@ export function setExampleTemplates() {
category: "song",
items: [
{
style: "top:120px;left:50px;height:840px;width:1820px;",
style: DEFAULT_ITEM_STYLE,
align: "",
lines: [{ align: "", text: [{ value: get(dictionary).example?.default || "Default", style: "font-size: 100px;" }] }],
},
Expand All @@ -239,7 +240,7 @@ export function setExampleTemplates() {
category: "song",
items: [
{
style: "top:120px;left:50px;height:840px;width:1820px;",
style: DEFAULT_ITEM_STYLE,
align: "",
lines: [{ align: "", text: [{ value: get(dictionary).example?.small || "Small", style: "font-size: 80px;" }] }],
},
Expand All @@ -251,7 +252,7 @@ export function setExampleTemplates() {
category: "song",
items: [
{
style: "top:120px;left:50px;height:840px;width:1820px;",
style: DEFAULT_ITEM_STYLE,
align: "",
lines: [
{
Expand All @@ -273,7 +274,7 @@ export function setExampleTemplates() {
category: "song",
items: [
{
style: "top:120px;left:50px;height:840px;width:1820px;",
style: DEFAULT_ITEM_STYLE,
align: "",
lines: [
{
Expand All @@ -295,7 +296,7 @@ export function setExampleTemplates() {
category: "song",
items: [
{
style: "top:120px;left:50px;height:840px;width:1820px;",
style: DEFAULT_ITEM_STYLE,
align: "",
lines: [
{
Expand Down Expand Up @@ -553,7 +554,7 @@ export function setExampleTemplates() {
category: "presentation",
items: [
{
style: "top:120px;left:50px;height:840px;width:1820px;",
style: DEFAULT_ITEM_STYLE,
align: "",
lines: [
{
Expand Down

0 comments on commit 776f465

Please sign in to comment.