mirror of
https://github.com/streamwall/streamwall.git
synced 2026-04-03 20:32:08 -04:00
Add ability to set stream audio playing in background
This commit is contained in:
@@ -29,6 +29,9 @@ function Overlay({ config, views, streams }) {
|
|||||||
const isListening = viewState.matches(
|
const isListening = viewState.matches(
|
||||||
'displaying.running.audio.listening',
|
'displaying.running.audio.listening',
|
||||||
)
|
)
|
||||||
|
const isBackgroundListening = viewState.matches(
|
||||||
|
'displaying.running.audio.background',
|
||||||
|
)
|
||||||
const isBlurred = viewState.matches('displaying.running.video.blurred')
|
const isBlurred = viewState.matches('displaying.running.video.blurred')
|
||||||
const isLoading = viewState.matches('displaying.loading')
|
const isLoading = viewState.matches('displaying.loading')
|
||||||
return (
|
return (
|
||||||
@@ -51,7 +54,7 @@ function Overlay({ config, views, streams }) {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
{isListening && <SoundIcon />}
|
{(isListening || isBackgroundListening) && <SoundIcon />}
|
||||||
</StreamTitle>
|
</StreamTitle>
|
||||||
)}
|
)}
|
||||||
{isLoading && <LoadingSpinner />}
|
{isLoading && <LoadingSpinner />}
|
||||||
|
|||||||
@@ -257,6 +257,10 @@ export default class StreamWindow extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setViewBackgroundListening(viewIdx, listening) {
|
||||||
|
this.sendViewEvent(viewIdx, listening ? 'BACKGROUND' : 'UNBACKGROUND')
|
||||||
|
}
|
||||||
|
|
||||||
setViewBlurred(viewIdx, blurred) {
|
setViewBlurred(viewIdx, blurred) {
|
||||||
this.sendViewEvent(viewIdx, blurred ? 'BLUR' : 'UNBLUR')
|
this.sendViewEvent(viewIdx, blurred ? 'BLUR' : 'UNBLUR')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -270,6 +270,8 @@ async function main() {
|
|||||||
const onMessage = async (msg, respond) => {
|
const onMessage = async (msg, respond) => {
|
||||||
if (msg.type === 'set-listening-view') {
|
if (msg.type === 'set-listening-view') {
|
||||||
streamWindow.setListeningView(msg.viewIdx)
|
streamWindow.setListeningView(msg.viewIdx)
|
||||||
|
} else if (msg.type === 'set-view-background-listening') {
|
||||||
|
streamWindow.setViewBackgroundListening(msg.viewIdx, msg.listening)
|
||||||
} else if (msg.type === 'set-view-blurred') {
|
} else if (msg.type === 'set-view-blurred') {
|
||||||
streamWindow.setViewBlurred(msg.viewIdx, msg.blurred)
|
streamWindow.setViewBlurred(msg.viewIdx, msg.blurred)
|
||||||
} else if (msg.type === 'set-custom-streams') {
|
} else if (msg.type === 'set-custom-streams') {
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ const viewStateMachine = Machine(
|
|||||||
on: {
|
on: {
|
||||||
MUTE: '.muted',
|
MUTE: '.muted',
|
||||||
UNMUTE: '.listening',
|
UNMUTE: '.listening',
|
||||||
|
BACKGROUND: '.background',
|
||||||
|
UNBACKGROUND: '.muted',
|
||||||
},
|
},
|
||||||
states: {
|
states: {
|
||||||
muted: {
|
muted: {
|
||||||
@@ -149,6 +151,13 @@ const viewStateMachine = Machine(
|
|||||||
listening: {
|
listening: {
|
||||||
entry: 'unmuteAudio',
|
entry: 'unmuteAudio',
|
||||||
},
|
},
|
||||||
|
background: {
|
||||||
|
on: {
|
||||||
|
// Ignore normal audio swapping.
|
||||||
|
MUTE: {},
|
||||||
|
},
|
||||||
|
entry: 'unmuteAudio',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
video: {
|
video: {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const operatorActions = new Set([
|
const operatorActions = new Set([
|
||||||
'set-listening-view',
|
'set-listening-view',
|
||||||
|
'set-view-background-listening',
|
||||||
'set-view-blurred',
|
'set-view-blurred',
|
||||||
'set-custom-streams',
|
'set-custom-streams',
|
||||||
'reload-view',
|
'reload-view',
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
import { State } from 'xstate'
|
import { State } from 'xstate'
|
||||||
import styled, { createGlobalStyle } from 'styled-components'
|
import styled, { createGlobalStyle } from 'styled-components'
|
||||||
import { useHotkeys } from 'react-hotkeys-hook'
|
import { useHotkeys } from 'react-hotkeys-hook'
|
||||||
|
import Color from 'color'
|
||||||
|
|
||||||
import '../index.css'
|
import '../index.css'
|
||||||
import { idxInBox } from '../geometry'
|
import { idxInBox } from '../geometry'
|
||||||
@@ -139,6 +140,9 @@ function useStreamwallConnection(wsEndpoint) {
|
|||||||
const isListening = state.matches(
|
const isListening = state.matches(
|
||||||
'displaying.running.audio.listening',
|
'displaying.running.audio.listening',
|
||||||
)
|
)
|
||||||
|
const isBackgroundListening = state.matches(
|
||||||
|
'displaying.running.audio.background',
|
||||||
|
)
|
||||||
const isBlurred = state.matches('displaying.running.video.blurred')
|
const isBlurred = state.matches('displaying.running.video.blurred')
|
||||||
for (const space of pos.spaces) {
|
for (const space of pos.spaces) {
|
||||||
if (!newStateIdxMap.has(space)) {
|
if (!newStateIdxMap.has(space)) {
|
||||||
@@ -147,6 +151,7 @@ function useStreamwallConnection(wsEndpoint) {
|
|||||||
Object.assign(newStateIdxMap.get(space), {
|
Object.assign(newStateIdxMap.get(space), {
|
||||||
state,
|
state,
|
||||||
isListening,
|
isListening,
|
||||||
|
isBackgroundListening,
|
||||||
isBlurred,
|
isBlurred,
|
||||||
spaces: pos.spaces,
|
spaces: pos.spaces,
|
||||||
})
|
})
|
||||||
@@ -332,6 +337,14 @@ function App({ wsEndpoint, role }) {
|
|||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const handleSetBackgroundListening = useCallback((viewIdx, listening) => {
|
||||||
|
send({
|
||||||
|
type: 'set-view-background-listening',
|
||||||
|
viewIdx,
|
||||||
|
listening,
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
const handleSetBlurred = useCallback((idx, blurred) => {
|
const handleSetBlurred = useCallback((idx, blurred) => {
|
||||||
send({
|
send({
|
||||||
type: 'set-view-blurred',
|
type: 'set-view-blurred',
|
||||||
@@ -504,8 +517,12 @@ function App({ wsEndpoint, role }) {
|
|||||||
<StyledGridLine>
|
<StyledGridLine>
|
||||||
{range(0, gridCount).map((x) => {
|
{range(0, gridCount).map((x) => {
|
||||||
const idx = gridCount * y + x
|
const idx = gridCount * y + x
|
||||||
const { isListening = false, isBlurred = false, state } =
|
const {
|
||||||
stateIdxMap.get(idx) || {}
|
isListening = false,
|
||||||
|
isBackgroundListening = false,
|
||||||
|
isBlurred = false,
|
||||||
|
state,
|
||||||
|
} = stateIdxMap.get(idx) || {}
|
||||||
const { streamId } = sharedState.views?.[idx] || ''
|
const { streamId } = sharedState.views?.[idx] || ''
|
||||||
const isDragHighlighted =
|
const isDragHighlighted =
|
||||||
dragStart !== undefined &&
|
dragStart !== undefined &&
|
||||||
@@ -517,6 +534,7 @@ function App({ wsEndpoint, role }) {
|
|||||||
isError={state && state.matches('displaying.error')}
|
isError={state && state.matches('displaying.error')}
|
||||||
isDisplaying={state && state.matches('displaying')}
|
isDisplaying={state && state.matches('displaying')}
|
||||||
isListening={isListening}
|
isListening={isListening}
|
||||||
|
isBackgroundListening={isBackgroundListening}
|
||||||
isBlurred={isBlurred}
|
isBlurred={isBlurred}
|
||||||
isHighlighted={isDragHighlighted}
|
isHighlighted={isDragHighlighted}
|
||||||
isSwapping={idx === swapStartIdx}
|
isSwapping={idx === swapStartIdx}
|
||||||
@@ -528,6 +546,7 @@ function App({ wsEndpoint, role }) {
|
|||||||
onBlur={handleBlurInput}
|
onBlur={handleBlurInput}
|
||||||
onChangeSpace={handleSetView}
|
onChangeSpace={handleSetView}
|
||||||
onSetListening={handleSetListening}
|
onSetListening={handleSetListening}
|
||||||
|
onSetBackgroundListening={handleSetBackgroundListening}
|
||||||
onSetBlurred={handleSetBlurred}
|
onSetBlurred={handleSetBlurred}
|
||||||
onReloadView={handleReloadView}
|
onReloadView={handleReloadView}
|
||||||
onSwapView={handleSwapView}
|
onSwapView={handleSwapView}
|
||||||
@@ -722,6 +741,7 @@ function GridInput({
|
|||||||
isDisplaying,
|
isDisplaying,
|
||||||
isError,
|
isError,
|
||||||
isListening,
|
isListening,
|
||||||
|
isBackgroundListening,
|
||||||
isBlurred,
|
isBlurred,
|
||||||
isHighlighted,
|
isHighlighted,
|
||||||
isSwapping,
|
isSwapping,
|
||||||
@@ -732,6 +752,7 @@ function GridInput({
|
|||||||
onFocus,
|
onFocus,
|
||||||
onBlur,
|
onBlur,
|
||||||
onSetListening,
|
onSetListening,
|
||||||
|
onSetBackgroundListening,
|
||||||
onSetBlurred,
|
onSetBlurred,
|
||||||
onReloadView,
|
onReloadView,
|
||||||
onSwapView,
|
onSwapView,
|
||||||
@@ -762,8 +783,17 @@ function GridInput({
|
|||||||
[idx, onChangeSpace],
|
[idx, onChangeSpace],
|
||||||
)
|
)
|
||||||
const handleListeningClick = useCallback(
|
const handleListeningClick = useCallback(
|
||||||
() => onSetListening(idx, !isListening),
|
(ev) =>
|
||||||
[idx, onSetListening, isListening],
|
ev.shiftKey || isBackgroundListening
|
||||||
|
? onSetBackgroundListening(idx, !isBackgroundListening)
|
||||||
|
: onSetListening(idx, !isListening),
|
||||||
|
[
|
||||||
|
idx,
|
||||||
|
onSetListening,
|
||||||
|
onSetBackgroundListening,
|
||||||
|
isListening,
|
||||||
|
isBackgroundListening,
|
||||||
|
],
|
||||||
)
|
)
|
||||||
const handleBlurClick = useCallback(() => onSetBlurred(idx, !isBlurred), [
|
const handleBlurClick = useCallback(() => onSetBlurred(idx, !isBlurred), [
|
||||||
idx,
|
idx,
|
||||||
@@ -839,7 +869,8 @@ function GridInput({
|
|||||||
)}
|
)}
|
||||||
{roleCan(role, 'set-listening-view') && (
|
{roleCan(role, 'set-listening-view') && (
|
||||||
<StyledButton
|
<StyledButton
|
||||||
isActive={isListening}
|
isActive={isListening || isBackgroundListening}
|
||||||
|
activeColor={isListening ? 'red' : Color('red').desaturate(0.5)}
|
||||||
onClick={handleListeningClick}
|
onClick={handleListeningClick}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
>
|
>
|
||||||
@@ -931,11 +962,11 @@ const StyledButton = styled.button`
|
|||||||
background: #ccc;
|
background: #ccc;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|
||||||
${({ isActive }) =>
|
${({ isActive, activeColor }) =>
|
||||||
isActive &&
|
isActive &&
|
||||||
`
|
`
|
||||||
border-color: red;
|
border-color: ${activeColor};
|
||||||
background: #c77;
|
background: ${Color(activeColor).desaturate(0.5).lighten(0.5)};
|
||||||
`};
|
`};
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
|
|||||||
Reference in New Issue
Block a user