이벤트의 공연 시간을 관리하는 묶음 "nodecg-timekeeper"
개시하다
최근에는 기술 강연과 행사의 온라인화가 진행 중이라고 생각한다.
저자는 RTA 커뮤니티에서 온라인 행사를 개최하는데 RTA 행사에서 다음과 같은 과제가 있다.
NodeCG
에서 공연 프로그램 시간을 관리했다.RTA 활동뿐만 아니라 온라인 활동의 시간 관리에 고민하는 분들을 도울 수 있다면 좋겠다고 생각합니다.
창고.
Why NodeCG?
이번에 NodecG 번들로 시행된 데는 몇 가지 이유가 있다.
덮어쓰는 프레임을 라우팅할 수 있습니다.
활동 자체의 현장 전송 커버 프레임은 NodecG로 같은 환경의 또 다른 번들로 이동할 수 있다.
또 번들 간 정보 교환 기능도 제공돼 활동용 번들과의 협업도 용이하다.
실시간 데이터 변경에 적합
NodecG의 특징이지만 호스트 간 실시간 데이터 변경에 뛰어나다.
타이머가 시작되는 작업을 운영하면 타이머 영상(웹 브라우저)에 반영할 시간이 거의 없다.시간 관리의 특성상 데이터의 변경은 시차가 없는 것이 중요하다.
데이터 보존 메커니즘
호스트 NodecG의 서버가 떨어졌든 데이터를 저장하든 모두 NodecG의 장점이다.
RTA 활동에서 이 프레임워크가 가장 인기 있는 이유는 게임 타이머 등 정보가 고장 났을 때도 빠지지 않기 때문이다.
설치 방법
필요 NodeCG 운영 환경
NodecG 설치 프로그램 [1]
nodecg-cli
NodecG가 설치된 디렉토리에서 다음 명령을 사용하여 설치할 수 있습니다.nodecg install cma2819/nodecg-timekeeper
기본 기능
설치를 시작하는 NodecG
cma2819/nodecg-timekeeper
.cd nodecg
nodecg start
조작 타이머
http://localhost:9090/dashboard/
로 대시보드를 엽니다.쓸 필요가 없을 정도로 간단하지만, 이것은 각 단추의 설명이다.
START
타이머는 0초부터 시작합니다.방송 시작하자마자 눌러.
FINISH
타이머를 종료합니다.재설정해야 하기 때문에 다시 시작할 수 없습니다.프로그램이 끝날 때 누르세요.
종료 시간은 패널 아래에 역사 기록으로 저장됩니다.
RESUME
일시 중지된 타이머를 복원합니다.
PAUSE
타이머를 일시 정지하다.공연 프로그램에 문제가 생겼을 때 누르세요.
RESET HISTORY
기록을 지웁니다.이력서가 너무 많이 쌓여서 잘 보이지 않는 경우를 누르세요.
공연 시간을 공유하다
시간이 지나면graphics로 표시되고 공유됩니다.
nodecg-timekeeper
자체적으로 간단한 시간 표시를 실시했기 때문에 저는 기본적으로 이곳에서 충분히 사용할 수 있다고 생각합니다.graphics는 원래 게시 덮어쓰기 도형을 제공하지만, 원래는 웹 페이지이기 때문에 브라우저로 열기도 쉽다.개봉
localhost:9090/bundles/nodecg-timekeeper/graphics/timekeeper.html
하면 경과 시간을 확인할 수 있습니다.이 URL을 연기자에게 공유하면'브라우저에 보여주세요'라는 한마디만 전달하면 드라마의 목적 경과 시간을 공유할 수 있다.
다른 뱅크스와의 합작
응용 프로그램으로, 다른 묶음 작업 타이머와 함께 새graphics에 시간을 표시할 수 있습니다.
하나의 예,
nodecg.sendMessageToBundle()
시작 타이머의 코드는 다음과 같다.메시징에 대해서는 다음을 참조하십시오.
설치 정보
dashboard/graphics는 React+TypeScript이고 extensions는 TypeScript로 이루어지며 반도라에서는 Webpack을 사용합니다.
dashboard/graphics
간단한 구성이라 특별히 언급할 점이 없었으나 노드CG에 있는 데이터(Replicant)를 읽을 때Context를 사용했다.
ReplicantProvider.tsx
ReplicantProvider.tsx
nodecg.sendMessageToBundle('nodecg-timekeeper', 'start')
.then(() => {
// タイマースタート後のコールバック処理
})
.catch((error: Error) => {
console.error(error);
});
dashboard에서 Replicant를 직접 변경하지 않고 extensions에 메시지를 전송합니다.패키지 구성 요소 예
dashboard/component/Timekeeper/TimekeepingControl.tsx
import { clone } from 'lodash';
import React, { createContext, ReactNode, useEffect, useState } from 'react';
import { History, Timekeeping } from '../nodecg/generated';
import { BundleNodecgInstance } from '../nodecg/nodecg';
interface Replicants {
timekeeping: Timekeeping;
history: History;
}
const defaultValues: Replicants = {
timekeeping: {
time: {
display: '00:00',
rawInSecond: 0,
},
status: 'finished',
},
history: [],
};
export const ReplicantContext = createContext<Replicants>(defaultValues);
type Props = {
children: ReactNode;
}
export const ReplicantProvider = ({ children }: Props) => {
const [timekeeping, setTimekeeping] = useState<Timekeeping>(defaultValues.timekeeping);
const [history, setHistory] = useState<History>(defaultValues.history);
useEffect(() => {
nodecg.Replicant('timekeeping').on('change', (newVal) => {
setTimekeeping(clone(newVal));
});
nodecg.Replicant('history').on('change', (newVal) => {
setHistory(clone(newVal));
});
}, []);
return (
<ReplicantContext.Provider value={{
timekeeping,
history,
}}>
{ children }
</ReplicantContext.Provider>
);
}
NodecG는 단점인 html 파일이 필요하기 때문에 페이지 구성 요소를 entry로 하고 HtmlWebpackPlugin를 통해 〃를 출력합니다.webpack.config
webpack.config.browser.ts
type Props = {
status: 'in_progress' | 'paused' | 'finished';
};
type MessageKey = keyof MessageMap;
export const TimekeepingControl = ({ status }: Props) => {
const action = (message: MessageKey) => {
(nodecg as BundleNodecgInstance).sendMessage(message);
}
return (
<Grid container spacing={2}>
<Grid item xs={6}>
<Button
color="primary"
startIcon={<FiberManualRecordIcon />}
disabled={ status !== 'finished' }
variant="contained"
fullWidth
onClick={() => { action('start') }}
>
Start
</Button>
</Grid>
...
</Grid>
)
}
extensions
이것도 간단한 노드다.js의 구현입니다. 하지만 타이머 부분에jest의 테스트가 적혀 있습니다.노드CG에 의존하는 테스트가 잘 안 되는 게 과제다.실천하는 동지는 반드시 나에게 알려주세요.
import { Configuration, Entry } from 'webpack';
import path from 'path';
import globby from 'globby';
import HtmlWebpackPlugin from 'html-webpack-plugin';
const targets = ['dashboard', 'graphics'];
const makeBrowserConfig = (target: string): Configuration => {
const entry: Entry = Object.fromEntries(
// path from root (where webpack.config.ts is in)
globby.sync(`./src/browser/${target}/pages/*.tsx`).map(
tsx => [ path.basename(tsx, '.tsx'), tsx ]
)
);
return {
entry,
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: 'ts-loader',
options: {
configFile: path.resolve(__dirname, '../src/browser/tsconfig.json'),
}
},
exclude: /node_modules/,
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
{
test: /\.png/,
type: 'asset/resource',
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, `../${target}`),
},
plugins: [
...
Object.keys(entry).map(
name => new HtmlWebpackPlugin({
title: `${name}`,
filename: `${name}.html`,
chunks: [name],
template: path.resolve(__dirname, `./templates/${target}.html`),
})
)
],
};
}
export const browserConfig: Array<Configuration> = targets.map(t => makeBrowserConfig(t));
총결산
간단한 타이머는 nodecg-timekeeper의 소개입니다.
사용 방법과 설치 모두 이해하기 쉬우니 NodecG 도입을 계기로 꼭 사용해 주십시오.
아울러 게임 활동뿐만 아니라 기술 관련 강연 등에서도 활용 보고서를 기대하고 있다.
각주
일본어 문장이 없어서 공식 문서입니다.기회가 된다면 설치와 운용에 관한 기사도 쓰세요...↩︎
Reference
이 문제에 관하여(이벤트의 공연 시간을 관리하는 묶음 "nodecg-timekeeper"), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/cma2819/articles/intro-ncg-timekeeper텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)