aaa
This commit is contained in:
parent
7be882acbd
commit
c3b0f5675b
4 changed files with 757 additions and 730 deletions
|
@ -240,6 +240,7 @@ class Session(object):
|
|||
except MediaStreamError as e:
|
||||
print(self.connection_id, e)
|
||||
await self.end()
|
||||
raise e
|
||||
if self.running:
|
||||
# Right, depending on the format, we may need to do some fuckery.
|
||||
# Jack expects all audio to be 32 bit floating point
|
||||
|
|
|
@ -21,6 +21,7 @@ export class WebRTCStreamer extends Streamer {
|
|||
}
|
||||
|
||||
async start(): Promise<void> {
|
||||
console.log("RTCStreamer start");
|
||||
this.pc = new RTCPeerConnection({
|
||||
iceServers: [
|
||||
{
|
||||
|
@ -52,6 +53,7 @@ export class WebRTCStreamer extends Streamer {
|
|||
};
|
||||
this.stream.getAudioTracks().forEach(track => this.pc!.addTrack(track));
|
||||
|
||||
console.log("PC created");
|
||||
this.ws = new WebSocket(process.env.REACT_APP_WS_URL!);
|
||||
this.ws.onopen = e => {
|
||||
console.log("WS open");
|
||||
|
@ -62,6 +64,7 @@ export class WebRTCStreamer extends Streamer {
|
|||
this.onStateChange(this.mapStateToConnectionState());
|
||||
};
|
||||
this.ws.addEventListener("message", this.onMessage.bind(this));
|
||||
console.log("WS created");
|
||||
}
|
||||
|
||||
async stop(): Promise<void> {
|
||||
|
|
|
@ -87,6 +87,16 @@ export const changeBroadcastSetting = <K extends keyof BroadcastState>(
|
|||
};
|
||||
|
||||
export const registerTimeslot = (): AppThunk => async (dispatch, getState) => {
|
||||
if (!getState().session.userCanBroadcast) {
|
||||
dispatch(
|
||||
NavbarState.showAlert({
|
||||
color: "warning",
|
||||
content: "You are not WebStudio Trained and cannot go live.",
|
||||
closure: 7000
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (getState().broadcast.stage === "NOT_REGISTERED") {
|
||||
var state = getState().session;
|
||||
const memberid = state.currentUser?.memberid;
|
||||
|
@ -95,6 +105,7 @@ export const registerTimeslot = (): AppThunk => async (dispatch, getState) => {
|
|||
var sourceid = getState().broadcast.sourceID;
|
||||
try {
|
||||
var connID = await sendBroadcastRegister(timeslotid, memberid, sourceid);
|
||||
console.log(connID);
|
||||
if (connID !== undefined) {
|
||||
dispatch(broadcastState.actions.setConnID(connID["connid"]));
|
||||
dispatch(startStreaming());
|
||||
|
@ -227,19 +238,14 @@ export function sendTracklistStart(trackid: number): Promise<TrackListItem> {
|
|||
}
|
||||
|
||||
export const startStreaming = (): AppThunk => async (dispatch, getState) => {
|
||||
if (!getState().session.userCanBroadcast) {
|
||||
dispatch(
|
||||
NavbarState.showAlert({
|
||||
color: "warning",
|
||||
content: "You are not WebStudio Trained and cannot go live.",
|
||||
closure: 7000
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log("starting streamer.");
|
||||
streamer = new WebRTCStreamer(MixerState.destination.stream);
|
||||
streamer.addConnectionStateListener(state => {
|
||||
dispatch(broadcastState.actions.setConnectionState(state));
|
||||
if (state === "CONNECTION_LOST") {
|
||||
// un-register if we drop, let the user manually reconnect
|
||||
dispatch(broadcastState.actions.setConnID(null));
|
||||
}
|
||||
});
|
||||
await streamer.start();
|
||||
};
|
||||
|
|
|
@ -13,7 +13,9 @@ import { Track, MYRADIO_NON_API_BASE, AuxItem } from "../api";
|
|||
import { AppThunk } from "../store";
|
||||
import { RootState } from "../rootReducer";
|
||||
import WaveSurfer from "wavesurfer.js";
|
||||
import { createLoudnessMeasurement } from "./loudness";
|
||||
|
||||
import NewsIntro from "../assets/audio/NewsIntro.wav";
|
||||
import NewsEndCountdown from "../assets/audio/NewsEndCountdown.wav";
|
||||
|
||||
const audioContext = new AudioContext();
|
||||
const wavesurfers: WaveSurfer[] = [];
|
||||
|
@ -38,6 +40,32 @@ export const destination = audioContext.createMediaStreamDestination();
|
|||
console.log("final destination", destination);
|
||||
finalCompressor.connect(destination);
|
||||
|
||||
const newsEndCountdownEl = new Audio(NewsEndCountdown);
|
||||
newsEndCountdownEl.preload = "auto";
|
||||
newsEndCountdownEl.volume = 0.5;
|
||||
const newsEndCountdownNode = audioContext.createMediaElementSource(
|
||||
newsEndCountdownEl
|
||||
);
|
||||
newsEndCountdownNode.connect(audioContext.destination);
|
||||
|
||||
const newsStartCountdownEl = new Audio(NewsIntro);
|
||||
newsStartCountdownEl.preload = "auto";
|
||||
newsStartCountdownEl.volume = 0.5;
|
||||
const newsStartCountdownNode = audioContext.createMediaElementSource(
|
||||
newsStartCountdownEl
|
||||
);
|
||||
newsStartCountdownNode.connect(audioContext.destination);
|
||||
|
||||
export async function playNewsEnd() {
|
||||
newsEndCountdownEl.currentTime = 0;
|
||||
await newsEndCountdownEl.play();
|
||||
}
|
||||
|
||||
export async function playNewsIntro() {
|
||||
newsStartCountdownEl.currentTime = 0;
|
||||
await newsStartCountdownEl.play();
|
||||
}
|
||||
|
||||
type PlayerStateEnum = "playing" | "paused" | "stopped";
|
||||
type PlayerRepeatEnum = "none" | "one" | "all";
|
||||
type VolumePresetEnum = "off" | "bed" | "full";
|
||||
|
@ -147,8 +175,7 @@ const mixerState = createSlice({
|
|||
item: PlanItem | Track | AuxItem;
|
||||
}>
|
||||
) {
|
||||
state.players[action.payload.player].loadedItem =
|
||||
action.payload.item;
|
||||
state.players[action.payload.player].loadedItem = action.payload.item;
|
||||
state.players[action.payload.player].loading = 0;
|
||||
state.players[action.payload.player].timeCurrent = 0;
|
||||
state.players[action.payload.player].timeRemaining = 0;
|
||||
|
@ -156,7 +183,10 @@ const mixerState = createSlice({
|
|||
state.players[action.payload.player].tracklistItemID = -1;
|
||||
state.players[action.payload.player].loadError = false;
|
||||
},
|
||||
itemLoadPercentage(state, action: PayloadAction<{ player: number, percent: number }>) {
|
||||
itemLoadPercentage(
|
||||
state,
|
||||
action: PayloadAction<{ player: number; percent: number }>
|
||||
) {
|
||||
state.players[action.payload.player].loading = action.payload.percent;
|
||||
},
|
||||
itemLoadComplete(state, action: PayloadAction<{ player: number }>) {
|
||||
|
@ -214,11 +244,9 @@ const mixerState = createSlice({
|
|||
time: number;
|
||||
}>
|
||||
) {
|
||||
state.players[action.payload.player].timeCurrent =
|
||||
action.payload.time;
|
||||
state.players[action.payload.player].timeCurrent = action.payload.time;
|
||||
state.players[action.payload.player].timeRemaining =
|
||||
state.players[action.payload.player].timeLength -
|
||||
action.payload.time;
|
||||
state.players[action.payload.player].timeLength - action.payload.time;
|
||||
},
|
||||
setTimeLength(
|
||||
state,
|
||||
|
@ -227,8 +255,7 @@ const mixerState = createSlice({
|
|||
time: number;
|
||||
}>
|
||||
) {
|
||||
state.players[action.payload.player].timeLength =
|
||||
action.payload.time;
|
||||
state.players[action.payload.player].timeLength = action.payload.time;
|
||||
},
|
||||
toggleAutoAdvance(
|
||||
state,
|
||||
|
@ -277,8 +304,7 @@ const mixerState = createSlice({
|
|||
id: number;
|
||||
}>
|
||||
) {
|
||||
state.players[action.payload.player].tracklistItemID =
|
||||
action.payload.id;
|
||||
state.players[action.payload.player].tracklistItemID = action.payload.id;
|
||||
},
|
||||
startMicCalibration(state) {
|
||||
state.mic.calibration = true;
|
||||
|
@ -370,9 +396,7 @@ export const load = (
|
|||
}
|
||||
});
|
||||
wavesurfer.on("play", () => {
|
||||
dispatch(
|
||||
mixerState.actions.setPlayerState({ player, state: "playing" })
|
||||
);
|
||||
dispatch(mixerState.actions.setPlayerState({ player, state: "playing" }));
|
||||
});
|
||||
wavesurfer.on("pause", () => {
|
||||
dispatch(
|
||||
|
@ -383,9 +407,7 @@ export const load = (
|
|||
);
|
||||
});
|
||||
wavesurfer.on("finish", () => {
|
||||
dispatch(
|
||||
mixerState.actions.setPlayerState({ player, state: "stopped" })
|
||||
);
|
||||
dispatch(mixerState.actions.setPlayerState({ player, state: "stopped" }));
|
||||
const state = getState().mixer.players[player];
|
||||
if (state.tracklistItemID !== -1) {
|
||||
dispatch(BroadcastState.tracklistEnd(state.tracklistItemID));
|
||||
|
@ -444,9 +466,11 @@ export const load = (
|
|||
const percent = progress.transferred / progress.total;
|
||||
if (percent !== 1) {
|
||||
console.log({ progress });
|
||||
dispatch(mixerState.actions.itemLoadPercentage({ player, percent}));
|
||||
dispatch(
|
||||
mixerState.actions.itemLoadPercentage({ player, percent })
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
const rawData = await result.arrayBuffer();
|
||||
|
@ -480,7 +504,10 @@ export const load = (
|
|||
}
|
||||
};
|
||||
|
||||
export const play = (player: number): AppThunk => async (dispatch, getState) => {
|
||||
export const play = (player: number): AppThunk => async (
|
||||
dispatch,
|
||||
getState
|
||||
) => {
|
||||
if (typeof wavesurfers[player] === "undefined") {
|
||||
console.log("nothing loaded");
|
||||
return;
|
||||
|
@ -498,9 +525,7 @@ export const play = (player: number): AppThunk => async (dispatch, getState) =>
|
|||
|
||||
if (state.loadedItem && "album" in state.loadedItem) {
|
||||
//track
|
||||
dispatch(
|
||||
BroadcastState.tracklistStart(player, state.loadedItem.trackid)
|
||||
);
|
||||
dispatch(BroadcastState.tracklistStart(player, state.loadedItem.trackid));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -585,12 +610,8 @@ export const setVolume = (
|
|||
playerGainTweens[player].tweens.forEach(tween => tween.pause());
|
||||
if (playerGainTweens[player].target === level) {
|
||||
delete playerGainTweens[player];
|
||||
dispatch(
|
||||
mixerState.actions.setPlayerVolume({ player, volume: uiLevel })
|
||||
);
|
||||
dispatch(
|
||||
mixerState.actions.setPlayerGain({ player, gain: volume })
|
||||
);
|
||||
dispatch(mixerState.actions.setPlayerVolume({ player, volume: uiLevel }));
|
||||
dispatch(mixerState.actions.setPlayerGain({ player, gain: volume }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -602,9 +623,7 @@ export const setVolume = (
|
|||
const volumeTween = new Between(currentLevel, uiLevel)
|
||||
.time(FADE_TIME_SECONDS * 1000)
|
||||
.on("update", (val: number) => {
|
||||
dispatch(
|
||||
mixerState.actions.setPlayerVolume({ player, volume: val })
|
||||
);
|
||||
dispatch(mixerState.actions.setPlayerVolume({ player, volume: val }));
|
||||
});
|
||||
const gainTween = new Between(currentGain, volume)
|
||||
.time(FADE_TIME_SECONDS * 1000)
|
||||
|
@ -615,9 +634,7 @@ export const setVolume = (
|
|||
}
|
||||
})
|
||||
.on("complete", () => {
|
||||
dispatch(
|
||||
mixerState.actions.setPlayerGain({ player, gain: volume })
|
||||
);
|
||||
dispatch(mixerState.actions.setPlayerGain({ player, gain: volume }));
|
||||
// clean up when done
|
||||
delete playerGainTweens[player];
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue