Skip to content

Commit

Permalink
Add Companion button to play arbitrary videos
Browse files Browse the repository at this point in the history
  • Loading branch information
zoton2 committed Feb 17, 2024
1 parent 2fd5efe commit 889325d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
29 changes: 27 additions & 2 deletions companion-plugin/companion-module-esa/src/actions.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
import { CompanionActionDefinition } from '@companion-module/base';
import type ModuleInstance from './index';

let instance: ModuleInstance;

export const videoPlayAction = (
videos: { name: string, sum: string }[],
): CompanionActionDefinition => ({
name: 'Video Play',
description: 'Plays the chosen video',
options: [
{
id: 'video',
type: 'dropdown',
label: 'Video',
choices: videos.map(({ name, sum }) => ({ id: sum, label: name })),
default: '',
},
],
callback: (action) => {
if (action.options.video) {
instance.wsSend({ name: 'video_play', value: action.options.video });
}
},
});

/**
* Called by module instance class when actions should be set up.
* @param instance Copy of current module instance class
*/
function initActions(instance: ModuleInstance) {
export function initActions(instance_: ModuleInstance) {
instance = instance_;
instance.setActionDefinitions({
// Blank action that can be attached if connection status is needed but nothing else.
// There may be another way of doing this, just not found it yet?
Expand Down Expand Up @@ -91,6 +116,6 @@ function initActions(instance: ModuleInstance) {
}
},
},
video_play: videoPlayAction([]),
});
}
export default initActions;
13 changes: 12 additions & 1 deletion companion-plugin/companion-module-esa/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { InstanceBase, InstanceStatus, SomeCompanionConfigField, runEntrypoint } from '@companion-module/base';
import { WebSocket } from 'ws';
import initActions from './actions';
import { initActions, videoPlayAction } from './actions';
import { Config, getConfigFields } from './config';
import { initFeedbacks, obsSceneFeedback, setObsSceneKeys } from './feedbacks';
import initPresets from './presets';
Expand Down Expand Up @@ -150,6 +150,17 @@ class ModuleInstance extends InstanceBase<Config> {
// Trigger this feedback check, needed on connection, not sure if needed
// for anything else, but safe to have.
this.checkFeedbacks('obsSceneFeedback');
} else if (msg.name === 'videos') {
// TODO: Reference type from another location?
const videos = msg.value as {
name: string;
sum: string;
// Other unimportant (at the moment) types omitted.
}[];
// Updates the dropdown with the video information.
this.setActionDefinitions({
video_play: videoPlayAction(videos),
});
}
});
}
Expand Down
22 changes: 21 additions & 1 deletion src/extension/companion.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { startPlaylist } from './intermission-player';
import companion from './util/companion';
import { wait } from './util/helpers';
import { get as nodecg } from './util/nodecg';
import obs, { changeScene } from './util/obs';
import { obsData, streamDeckData } from './util/replicants';
import { assetsVideos, obsData, streamDeckData, videoPlayer } from './util/replicants';
import { sc } from './util/speedcontrol';

const config = nodecg().bundleConfig;
Expand All @@ -20,6 +22,7 @@ twitchCommercialsDisabled.on('change', (value) => (
companion.send({ name: 'twitchCommercialsDisabled', value })));
obsData.on('change', (value) => (
companion.send({ name: 'obsData', value: { ...value, gameLayoutScreenshot: undefined } })));
assetsVideos.on('change', (value) => companion.send({ name: 'videos', value }));

// Sending things on connection.
companion.evt.on('open', (socket) => {
Expand All @@ -30,6 +33,7 @@ companion.evt.on('open', (socket) => {
companion.send({ name: 'twitchCommercialsDisabled', value: twitchCommercialsDisabled.value });
companion.send({ name: 'obsData', value: { ...obsData.value, gameLayoutScreenshot: undefined } });
companion.send({ name: 'cfgScenes', value: nodecg().bundleConfig.obs.names.scenes });
companion.send({ name: 'videos', value: assetsVideos.value });
});

// Listening for any actions triggered from Companion.
Expand Down Expand Up @@ -107,5 +111,21 @@ companion.evt.on('action', async (name, value) => {
const val = value as string;
const scene = (scenes as { [k: string]: string })[val];
await changeScene({ scene, force: true });
// Used to play back a single video in the "Intermission Player" scene,
// intended to be used by hosts.
} else if (name === 'video_play') {
const val = value as string;
const video = assetsVideos.value.find((v) => v.sum === val);
if (video) {
videoPlayer.value.playlist = [
{
sum: video.sum,
length: 0,
commercial: false,
},
];
wait(500); // Safety wait
await startPlaylist();
}
}
});

0 comments on commit 889325d

Please sign in to comment.