Skip to content

Instantly share code, notes, and snippets.

@wakita
Last active September 30, 2020 05:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wakita/f3cfd8930eec9440d1bafa833cef411e to your computer and use it in GitHub Desktop.
Save wakita/f3cfd8930eec9440d1bafa833cef411e to your computer and use it in GitHub Desktop.
オンライン発表の時代のタイムキーパー用ツール

オンライン発表の時代のタイムキーパー用ツール

Zoom 時代の発表会運営をスムーズにするためにタイムキーパー用に作ったツールです.

  1. 発表開始からの経過時刻を秒単位で表示します.
  2. 発表開始から指定された時間が経過すると,作業内容の指示を発話できます.タイムキーパーは時計を常時,気にかける負担から開放されます.
  3. 発表開始から指定された時間が経過すると,定型的な文章をコピーバッファにコピーします.発表参加者と共有しているチャットツールにペーストして,座長,発表者,参加者に時間経過を通知できます.

必要なパッケージのインストール

pip install pyperclip: システムのコピーバッファへのテキストのコピーに使っています

指示の設定方法

指示のタイミングと内容は EVENTS 変数で設定します.

EVENTS 変数には,開始からの秒数と,その秒数が経過したときに実行して欲しいイベント関数名を与える.

イベント関数には任意のコードが記述できるので各自工夫して下さい.小便利関数として kyoko と copy を提供しています.

  • copy 関数はコピーバッファに与えられたテキストをコピーします.チャット等へのペーストを想定しています.

  • kyoko 関数は「Kyokoさん」の声で日本語を読み上げます.macOS の say コマンドに依存しています.

テスト方法

このコマンドを引数を与えて起動すると通常の20倍速で動作します.短時間で実行の様子を検証するのみ便利です.

使い方

発表会の都合にあわせて,メッセージや発話の内容を調整したら,

  • テスト実行(20倍速): ./timer.py --test

  • 本番実行: ./timer.py

#!/usr/bin/env python3
import curses, curses.ascii
from datetime import datetime
import subprocess
import sys
from pyperclip import copy
STOPSET = set([curses.ascii.SP, curses.ascii.ESC, ord('q'), ord('Q')])
UNIT = 60 / (1 if len(sys.argv) == 1 else 20)
try:
with open('chat.txt') as r:
CHAT = r.read()
except: CHAT = None
def kyoko(message):
subprocess.Popen(['say', '-v', 'Kyoko', message])
def event0():
if CHAT: copy(CHAT)
kyoko('仮想デスクトップをリセットして下さい。' +
'チャットに発表者情報などを表示して下さい。')
def event12():
kyoko('発表終了まであと3分です')
copy('発表終了まであと約3分です')
def event15():
kyoko('質疑の時間です')
copy('質疑の時間です')
def event20():
kyoko('つぎの発表が始まります')
copy('つぎの発表が始まります')
EVENTS = [(UNIT * sec, event) for sec, event in
[(0, event0), (12, event12), (15, event15), (20, event20)]]
def run(win):
curses.echo()
win.timeout(1000) # キー入力を最大1秒だけ待つ
start = datetime.now()
while not win.getch() in STOPSET and len(EVENTS) > 0:
total_secs = int((datetime.now() - start).total_seconds())
minutes, seconds = divmod(total_secs, 60)
win.addstr(0, 0, f'{minutes:02}:{seconds:02d}')
t, event = EVENTS[0]
if total_secs > t:
event()
EVENTS[0:1] = []
curses.wrapper(run)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment