1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ヘッドフォンを置いたときに音楽を止めるデバイスを作る

Last updated at Posted at 2023-04-24

トイレとか食事の時にヘッドフォンを外してYoutubeやらMusicやらを止めて...ってやるのがめんどくさかったのでヘッドフォンを置いた時に勝手に止めるようなデバイスを作りました。
デバイスと言いつつほとんどソフトウェア側の実装です。
また、MacOSでしか動きません。
完成したコードはここからダウンロードできます

用意するもの

  • ヘッドフォン
  • パソコン(MacOS以外は想定してないです)
  • Arduino(Arduino IDEで書き込めれば何でも良い)
  • リードスイッチ(磁石に反応するセンサ)
  • 磁石

リードスイッチじゃなくても大丈夫です。スイッチとか

組み立て

Arduinoとリードスイッチを以下のように接続します。
image.png
https://learn.sparkfun.com/tutorials/reed-switch-hookup-guide?_ga=2.265836815.1235452650.1682338515-855519520.1682338515 より引用

デバイスは以下のようなものを作成しました。
Screenshot 2023-04-24 at 21.24.44.png
スタンドの上部にリードスイッチをつけ、スタンドとヘッドフォンが接触する場所に磁石をつけます。こうすることでリードスイッチが反応するので置いたかどうか判断できます。

コード

Arduinoに書き込むコードです。

const int REED = 2;
bool is_placed = false;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(REED, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
  int prox = digitalRead(REED);
  if (prox == 0) {
    if (is_placed == false) {
      Serial.println("detected");
      is_placed = true;
    }
  } else {
    if (is_placed == true) {
      is_placed = false;
    }
  }
  delay(500);
}

やってることはREEDピンからの値が0になったら"detected"と出力しているだけです。何度も"detected"を送るのが嫌なので前フレームで出力した時は出力しないようにしています。

ブラウザやアプリを直接操作するためにAppleScriptを使います。
AppleScriptのコードです。

to muteSafari()
	if application "Safari" is running then
		tell application "Safari"
			try
				set windowcount to number of windows
                --ウィンドウ数でループ
				repeat with x from 1 to windowcount
                    --タブ数でループ
					set tabcount to number of tabs in window x
					repeat with y from 1 to tabcount
						set tabName to name of tab y of window x
						set tabURL to URL of tab y of window x
						set temp to "youtube"
                        --タブのurlにyoutubeという文字が含まれていたら
						if (offset in tabURL of temp) > 0 then
                            --再生中か否かを取得
							set isPaused to (do JavaScript "document.querySelector('#movie_player video').paused" in tab y of window x)
                            --再生中なら再生ボタンをクリックし、停止
							if isPaused = false then
								set theScript to "document.getElementsByClassName('ytp-play-button')[0].click()"
								do JavaScript theScript in tab y of window x
							end if
						end if
					end repeat
				end repeat
			end try
		end tell
	end if
end muteSafari
to muteMusic()
    --Musicが再生中なら
	if application "Music" is running then
        --音楽を止める
		tell application "Music" to pause
	end if
end muteMusic
to muteChrome()
	if application "Google Chrome" is running then
		tell application "Google Chrome"
			try
				set windowcount to number of windows
				
				repeat with z from 1 to windowcount
					set tabcount to number of tabs in window z
					repeat with w from 1 to tabcount
						--Get Tab Name & URL
						set tabName to title of tab w of window z
						set tabURL to URL of tab w of window z
						set temp to "youtube"
						if (offset in tabURL of temp) > 0 then
							set isPaused to (execute of tab w of window z javascript "document.querySelector('#movie_player video').paused")
							if isPaused = false then
								set theScript to "document.getElementsByClassName('ytp-play-button')[0].click()"
								execute of tab w of window z javascript theScript
							end if
						end if
					end repeat
				end repeat
			end try
		end tell
	end if
end muteChrome
muteSafari()
muteMusic()
muteChrome()

とても見辛いのですが、やっていることは

  • SafariのYoutubeを止める
  • ChromeのYoutubeを止める
  • Musicを止める
    の三つです。関数はそれぞれmuteSafari, muteChrome, muteMusicです。

Arduinoからの出力を受け取るPythonコードを書きます。

import serial
import atexit
import subprocess
import sys
import os

ser = serial.Serial("シリアルポート名", 115200)

def all_done():
    # 終了時の処理
    print("\nDone!")
    ser.close()

def main():
    atexit.register(all_done)
    try:
        while(True):
            line = ser.readline().strip().decode('utf-8')
            # 何かしらのトリガーがあったらスクリプトを実行する。
            # 今回はシリアルモニタから"detected"という文字列が送られてきたら実行する。
            if line == "detected":
                subprocess.run(["osascript", "/path/to/stopyoutube.scpt"])
                print("stopped!")

    except KeyboardInterrupt:
        sys.exit(0)


if __name__ == "__main__":
    main()

シリアルモニタを読んで、"detected"を検知したら先ほどのAppleScriptを実行しているだけです。

動かす

$ python runapplescript.py

ブラウザで動かしていたYoutube、Musicが止まれば成功です

ありがとうございました。

参考文献

Reed Switch Hookup Guide
AppleScriptでアプリケーションのウインドウ数を取得

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?