更新 (2021/03/05)
もっとスマートなZoomミーティング入室を行う方法があったみたいです....
ZOOMに自動的に接続する方法(コピペで簡単)
上の記事で紹介されているコマンドを用いて自動入室を行い、それに加えてPywinautoで画面キャプチャと自動退出をするという方式に変更しました。
それによりSeleniumは不要になりました。
この記事は今回の変更をすべて反映しています。
概要
Zoomミーティングに自動入室して画面キャプチャを行うスクリプトを作りました。
簡潔に言えば、「リアルタイム授業をオンデマンド授業にしよう」って感じです。
新型コロナウイルスによる影響でほとんどの学校でオンライン授業を強いられているかと思います。
オンライン授業に伴い、ビデオコミュニケーションツールであるZoomを利用している方も多いと思います。
そんな中で、なにか**急な用事ができて授業を受けられない!**みたいなことが起きるかもしれませんよね?
すごく困りますよね?こういうときどうしますか?
友達のノートを写させてもらいますか?友達にZoom授業を録画してもらって送ってもらいますか?
でも、それって少なからず友達に迷惑をかけますし、もっと言えば友達に頼めない状況下だったら....(悲しい)
そんなもしもの状況に立ち向かうためのスクリプトです。
僕は上に記したようなどうしても、やむを得ずZoom授業に参加できない状況下にあるときのみの利用を想定して作ったので、
決して、決して、"授業サボりたい"とか"寝坊しても安心"とかそういう悪いこと考えての利用は駄目ですよ!!
環境
-Software-
Windows 10 Home
Anaconda3 64-bit(Python3.8)
VSCode
Zoom 5.4.9
-Library-
Pywinauto 0.6.8
-Hardware-
CPU: Intel core i9 9900K
RAM: 16GB 3200MHz
参考
・ZOOMに自動的に接続する方法(コピペで簡単)
・オンライン授業にPython+Seleniumで自動出席したい!
・Pywinautoリファレンス
・pywinauto の使い方メモ
非推奨事項・免責事項
非推奨事項
概要でも触れたとおり、本スクリプトは、
やむを得ずZoom授業に参加できない状況下にあるときのみの利用を想定して作成しました。
それ以外の目的での利用は非推奨です。
また、上記の目的にしても、然るべき者に事情を伝え承認を得ましょう。
免責事項
本スクリプトの利用で発生したあらゆる損失や不利益について、筆者は一切の責任を負いません。
利用は自己責任でお願いします。
ソースコード
from pywinauto import Application
import pywinauto
import time
def captureZoom():
while True:
try:
# Zoomミーティングウィンドウ情報取得
zoom = Application(backend="uia").connect(best_match=u"Zoom ミーティング")
break
except pywinauto.findbestmatch.MatchError: # Zoomミーティング入室していない -> 再取得
continue
zoom[u"Zoom ミーティング"].set_focus() # 録画対象
pywinauto.keyboard.send_keys("{VK_LWIN down}%{R down}{VK_LWIN up}{R up}") # 録画開始
time.sleep(5400) # 90分
pywinauto.keyboard.send_keys("{VK_LWIN down}%{R down}{VK_LWIN up}{R up}") # 録画終了
# Zoom Client閉じる
zoom = Application(backend="uia").connect(best_match=u"Zoom ミーティング")
if zoom[u"Zoom ミーティング"].exists():
zoom[u"Zoom ミーティング"].set_focus()
pywinauto.keyboard.send_keys("%{F4}")
pywinauto.keyboard.send_keys("{ENTER}")
def main():
try:
captureZoom()
except pywinauto.findbestmatch.MatchError: # ターゲットが見つからなかった -> 再試行
print("The dialog was not found. Retrying...")
main()
except pywinauto.findwindows.ElementNotFoundError: # ターゲットが見つからなかった -> 再試行
print("The dialog was not found. Retrying...")
main()
if __name__ == '__main__':
main()
実行結果・諸注意・使い方
実行結果
動作の様子(Youtube)
諸注意
1. スクリプト実行中はマウス操作・キーボード操作をしないようにお願いします。
↑ スクリプト実行始めと終わり時以外であれば操作しても問題ないです。
2. ミーティング退出は指定時間経過により退出します。
3. ミーティングID、パスワードが固定されている場合のみ有用です。
4. Zoomは最新バージョンに更新してください。
5. 本スクリプトでは画面キャプチャにWindows10 PC標準機能のゲームバーの画面録画機能を使っています。そのためWindows10以外のOSでは動作しません。
使い方
まず、Pywinautoをインストールしましょう。
pip install pywinauto
次にスクリプトに記述されているtime.sleep()のカッコ内に授業時間を秒単位で入力してください。
time.sleep(5400) # 授業時間90分 = 5400秒
保存したら、メモ帳で下のようなbatファイルを作成。
set MEETINGID=<meeting_id>
set PASSWORD=<hashing_pass>
start zoommtg:"//zoom.us/join?action=join&confno=%MEETINGID%&pwd=%PASSWORD%"
python <script-path>
timeout /t <wait-time>
<meeting_id>
はミーティングIDです。
<hashing_pass>
はハッシュ化されたパスワードです。
上2つは招待URLから取り出してコピペしてください。(詳細)
https://zoom.us/j/<meeting_id>?pwd=<hashing_pass>
招待URL上の<meeting_id>と<hashing_pass>を取り出して、batファイルに記述。
<script-path>
はスクリプトファイルのパスです。
<wait-time>
はスクリプト実行終了後の待機時間です。
batファイルを作成できたら、タスクスケジューラで任意の時間にbatファイルを実行するように設定します。
ここの説明は割愛します。こちらを参考にしてください。
あとは設定した時間にPCが起動されていれば、スクリプトが実行されるはずです。
説明
一応スクリプトの説明をしておきます。
まずライブラリですが、
PywinautoはWindows操作をPythonで自動化できるライブラリです。キーボード入力やマウス操作、
スクリプトの説明です。
def main():
try:
captureZoom()
except pywinauto.findbestmatch.MatchError: # ターゲットが見つからなかった -> 再試行
print("The dialog was not found. Retrying...")
main()
except pywinauto.findwindows.ElementNotFoundError: # ターゲットが見つからなかった -> 再試行
print("The dialog was not found. Retrying...")
main()
pywinauto.findbestmatch.MatchError
はPywinautoの例外で検索対象のウィンドウが存在しなかった場合に発生します。
pywinauto.findwindows.ElementNotFoundError
も上の例外とほぼ同じです。
例外発生時は再実行するようにしています。
def captureZoom():
while True:
try:
# Zoomミーティングウィンドウ情報取得
zoom = Application(backend="uia").connect(best_match=u"Zoom ミーティング")
break
except pywinauto.findbestmatch.MatchError: # Zoomミーティング入室していない -> 再取得
continue
zoom[u"Zoom ミーティング"].set_focus() # 録画対象
pywinauto.keyboard.send_keys("{VK_LWIN down}%{R down}{VK_LWIN up}{R up}") # 録画開始
time.sleep(5400) # 90分
pywinauto.keyboard.send_keys("{VK_LWIN down}%{R down}{VK_LWIN up}{R up}") # 録画終了
# Zoom Client閉じる
zoom = Application(backend="uia").connect(best_match=u"Zoom ミーティング")
if zoom[u"Zoom ミーティング"].exists():
zoom[u"Zoom ミーティング"].set_focus()
pywinauto.keyboard.send_keys("%{F4}")
pywinauto.keyboard.send_keys("{ENTER}")
コマンド実行によりZoomミーティングに自動入室すると、Zoomミーティングという名前のウィンドウが出ますから、そのウィンドウの情報を取得します。まだ入室していなければ再度取得を試みます。
while True:
try:
# Zoomミーティングウィンドウ情報取得
zoom = Application(backend="uia").connect(best_match=u"Zoom ミーティング")
break
except pywinauto.findbestmatch.MatchError: # Zoomミーティング入室していない -> 再取得
continue
ウィンドウ情報取得後、録画対象としてウィンドウフォーカスしてゲームバーの画面録画機能による録画を開始します。
ゲームバーの画面録画はWin+Alt+R
で録画/停止できますので、Pywinautoでそのようなキーボード操作をするように記述します。
そしてtime.sleep()
で指定した時間が経過次第、録画を止めます。
zoom[u"Zoom ミーティング"].set_focus() # 録画対象
pywinauto.keyboard.send_keys("{VK_LWIN down}%{R down}{VK_LWIN up}{R up}") # 録画開始
time.sleep(5400) # 90分
pywinauto.keyboard.send_keys("{VK_LWIN down}%{R down}{VK_LWIN up}{R up}") # 録画終了
Zoomミーティングを退室する処理は結構力技で、ウィンドウフォーカスした後、Alt+F4
でウィンドウを閉じるショートカットを送信します。
そうすると、ミーティングを退出
というダイアログがでてくるのでEnter
で決定し退出します。
# Zoom Client閉じる
zoom = Application(backend="uia").connect(best_match=u"Zoom ミーティング")
if zoom[u"Zoom ミーティング"].exists():
zoom[u"Zoom ミーティング"].set_focus()
pywinauto.keyboard.send_keys("%{F4}")
pywinauto.keyboard.send_keys("{ENTER}")
おわりに
以上となります。
正直、こちらのスクリプトは公開しようか迷ったのですが、Pywinautoという神ライブラリを知ってほしかったので、こんなことができるぞ!という意も込めて公開しました。
また、オンライン授業にPython+Seleniumで自動出席したい!という記事で試行錯誤してChromeダイアログがSeleniumで操作できずに実現できなかったということだったので、なんとかならないかなと思った次第でもありました。
そして何度も言いますが悪用は厳禁です。