How to pause YouTube video via keyboard shortcut or from menu bar?
Solution 1:
********** UPDATED SOLUTION **********
This update is a direct solution to the OP's original question.
This following AppleScript code will add a "Play/Pause YouTube" status menu item with the options to play or pause any YouTube video in either Google Chrome or Safari, whether the browsers are visible or not. Save this following AppleScript code as a "stay open" application in Script Editor.app.
use framework "Foundation"
use framework "AppKit"
use scripting additions
property StatusItem : missing value
property selectedMenu : ""
property defaults : class "NSUserDefaults"
property internalMenuItem : class "NSMenuItem"
property externalMenuItem : class "NSMenuItem"
property newMenu : class "NSMenu"
my makeStatusBar()
my makeMenus()
on makeStatusBar()
set bar to current application's NSStatusBar's systemStatusBar
set StatusItem to bar's statusItemWithLength:-1.0
-- set up the initial NSStatusBars title
StatusItem's setTitle:"Play/Pause YouTube"
-- set up the initial NSMenu of the statusbar
set newMenu to current application's NSMenu's alloc()'s initWithTitle:"Custom"
newMenu's setDelegate:me (*
Requied delegation for when the Status bar Menu is clicked the menu will use the delegates method (menuNeedsUpdate:(menu)) to run dynamically update.*)
StatusItem's setMenu:newMenu
end makeStatusBar
on makeMenus()
newMenu's removeAllItems() -- remove existing menu items
set someListInstances to {"Play/Pause YouTube - Safari", "Play/Pause YouTube - Chrome", "Quit"}
repeat with i from 1 to number of items in someListInstances
set this_item to item i of someListInstances
set thisMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:this_item action:("someAction" & (i as text) & ":") keyEquivalent:"")
(newMenu's addItem:thisMenuItem)
(thisMenuItem's setTarget:me) -- required for enabling the menu item
end repeat
end makeMenus
on someAction1:sender
clickClassName2("ytp-play-button ytp-button", 0)
end someAction1:
on someAction2:sender
clickClassName("ytp-play-button ytp-button", 0)
end someAction2:
on someAction3:sender
quit me
end someAction3:
to clickClassName2(theClassName, elementnum)
if application "Safari" is running then
try
tell application "Safari"
tell window 1 to set current tab to tab 1 whose URL contains "youtube"
do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();" in document 1
end tell
end try
end if
end clickClassName2
to clickClassName(theClassName, elementnum)
tell application "Google Chrome" to (tabs of window 1 whose URL contains "youtube")
set youtubeTabs to item 1 of the result
tell application "Google Chrome"
execute youtubeTabs javascript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();"
end tell
end clickClassName
If you want your new... Play Pause YouTube Status Menu.app to only be visible in the status menu and not in the Dock, you can right-click on the app in Finder and select the option to "Show Package Contents". In the Contents folder, open the Info.plist file in any text editor and add the following two lines. Then save and close that file.
<key>LSBackgroundOnly</key>
<true/>
If you are not comfortable editing the .plist file directly, this following AppleScript code will allow you to choose the application to hide from the Dock when it is running.
If the chosen application is already set to be hidden from the Dock, the only option you will be given is to unhide the application from being visible in the Dock while it is running… And vice versa.
This script is especially handy for a hiding "stay open applications" with idle handlers' application icons from appearing in the Dock while running.
property fileTypes : {"com.apple.application-bundle"}
property plistFileItem : " <key>LSBackgroundOnly</key>" & linefeed & " <true/>"
activate
set chosenApp to (choose application with prompt ¬
"Choose The Application You Want Hidden From The Dock While It Is Running" as alias)
tell application "System Events" to set appName to name of chosenApp
set plistFile to ((POSIX path of chosenApp) & "/Contents/info.plist") as string
set plistFileContents to (read plistFile)
set plistFileItemExists to plistFileItem is in plistFileContents
if plistFileItemExists then
activate
set theChoice to button returned of (display dialog ¬
"Would you like to un-hide " & quote & appName & quote & ¬
" from the Dock while it's running?" buttons {"Cancel", "Un-Hide"} ¬
default button 2 cancel button 1 with title "Make A Choice")
else
activate
set theChoice to button returned of (display dialog ¬
"Would you like to hide " & quote & appName & quote & ¬
" from the Dock while it's running?" buttons {"Cancel", "Hide"} ¬
default button 2 cancel button 1 with title "Make A Choice")
end if
if theChoice is "Hide" then
tell application "System Events" to tell contents of property list file plistFile ¬
to make new property list item at end with properties ¬
{kind:string, name:"LSBackgroundOnly", value:true}
else if theChoice is "Un-Hide" then
tell application "System Events" to tell contents of property list file plistFile ¬
to make new property list item at end with properties ¬
{kind:string, name:"LSBackgroundOnly", value:false}
else
return
end if
************ ORIGINAL SOLUTION ************
This script will click on the Play/Pause button on a video playing in YouTube in Google Chrome, whether or not Google Chrome is visible.
to clickClassName(theClassName, elementnum)
tell application "Google Chrome" to (tabs of window 1 whose URL contains "youtube")
set youtubeTabs to item 1 of the result
tell application "Google Chrome"
execute youtubeTabs javascript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();"
end tell
end clickClassName
clickClassName("ytp-play-button ytp-button", 0)
This is the script version to work with Safari
to clickClassName2(theClassName, elementnum)
tell application "Safari"
tell window 1 to set current tab to tab 1 whose URL contains "youtube"
do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();" in document 1
end tell
end clickClassName2
clickClassName2("ytp-play-button ytp-button", 0)
In an effort to give the OP A complete AppleScript solution, I have taken my original answer one step further..
UPDATE
I finally figured it out. I created an AppleScript application in Xcode. Originally, my project only started with a one button window to control YouTube videos currently active in Chrome or Safari. This project has grown a little bit into an application that contains several utilities. This GIF shows the YouTube Pause button controlling YouTube in Chrome and Safari. I linked the button actions to the AppleScript I originally wrote in script editor.
This is a snapshot of the Xcode application Working in the AppDelegate.applescript file.
Here is the code in that file I created to make the program work.
script AppDelegate
property parent : class "NSObject"
-- IBOutlets
property theWindow : missing value
to clickClassName(theClassName, elementnum) -- Handler for pausing YouTube in Chrome
if application "Google Chrome" is running then
try
tell application "Google Chrome" to (tabs of window 1 whose URL contains "youtube")
set youtubeTabs to item 1 of the result
tell application "Google Chrome"
execute youtubeTabs javascript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();"
end tell
end try
end if
end clickClassName
to clickClassName2(theClassName, elementnum) -- Handler for pausing YouTube in Safari
if application "Safari" is running then
try
tell application "Safari"
tell window 1 to set current tab to tab 1 whose URL contains "youtube"
do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();" in document 1
end tell
end try
end if
end clickClassName2
on doSomething:sender -- Calls the Chrome YouTube Handler
clickClassName("ytp-play-button ytp-button", 0)
end doSomething:
on doSomething14:sender -- Calls the Safari YouTube Handler
clickClassName2("ytp-play-button ytp-button", 0)
end doSomething14:
on doSomething2:sender -- Hide and or show the Menu Bar
tell application "System Preferences"
reveal pane id "com.apple.preference.general"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "General"
click checkbox "Automatically hide and show the menu bar"
end tell
delay 1
quit application "System Preferences"
end doSomething2:
on doSomething3:sender -- Sets Display resolution to the second lowest setting (15 inch Built In Retina Display - MBP)
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "Built-in Retina Display"
click radio button "Scaled" of radio group 1 of tab group 1
click radio button 2 of radio group 1 of group 1 of tab group 1
end tell
quit application "System Preferences"
end doSomething3:
on doSomething4:sender -- Sets Display resolution to the second highest setting (15 inch Built In Retina Display - MBP)
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "Built-in Retina Display"
click radio button "Scaled" of radio group 1 of tab group 1
click radio button 4 of radio group 1 of group 1 of tab group 1
end tell
quit application "System Preferences"
end doSomething4:
on doSomething5:sender -- Sets Display resolution to the highest setting (15 inch Built In Retina Display - MBP)
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "Built-in Retina Display"
click radio button "Scaled" of radio group 1 of tab group 1
click radio button 5 of radio group 1 of group 1 of tab group 1
end tell
quit application "System Preferences"
end doSomething5:
on doSomething6:sender -- Sets Display resolution to the lowest setting (15 inch Built In Retina Display - MBP)
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "Built-in Retina Display"
click radio button "Scaled" of radio group 1 of tab group 1
click radio button 1 of radio group 1 of group 1 of tab group 1
delay 0.1
click button "OK" of sheet 1
quit application "System Preferences"
end tell
end doSomething6:
on doSomething7:sender -- Displays a dialog with your current IP
tell current application to display dialog (do shell script "curl ifconfig.io") with icon 2 buttons "OK" default button 1 with title "Your Current IP Address Is.." giving up after 5
end doSomething7:
on doSomething8:sender -- Shows hidden files in Finder
do shell script "defaults write com.apple.finder AppleShowAllFiles TRUE\nkillall Finder"
end doSomething8:
on doSomething9:sender -- Hides hidden files in Finder if they are showing
do shell script "defaults write com.apple.finder AppleShowAllFiles FALSE\nkillall Finder"
end doSomething9:
on doSomething10:sender -- Brightness Highest
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "Built-in Retina Display"
set value of value indicator 1 of slider 1 of group 2 of tab group 1 to 12
end tell
quit application "System Preferences"
end doSomething10:
on doSomething11:sender -- Brightness Lowest
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "Built-in Retina Display"
set value of value indicator 1 of slider 1 of group 2 of tab group 1 to 0.1
end tell
quit application "System Preferences"
end doSomething11:
on doSomething12:sender -- Zoom
tell application "System Events"
key code 28 using {command down, option down}
end tell
end doSomething12:
on doSomething13:sender -- Dictation On/Off
tell application "System Events"
keystroke "x" using {option down}
end tell
end doSomething13:
on doSomething15:sender -- Enables Screensaver as Desktop background
tell application "System Events"
do shell script "/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background"
end tell
end doSomething15:
on doSomething16:sender -- Kills Screensaver Desktop background
try
tell application id "com.apple.ScreenSaver.Engine" to quit
end try
end doSomething16:
on applicationWillFinishLaunching:aNotification
-- Insert code here to initialize your application before any files are opened
end applicationWillFinishLaunching:
on applicationShouldTerminate:sender
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate:
on applicationShouldTerminateAfterLastWindowClosed:sender -- Quits app when clicking red x
return TRUE
end applicationShouldTerminateAfterLastWindowClosed:
end script
I updated the code so that the YouTube tab in Chrome doesn't need to be the visible or active tab when clicking the YouTube Pause Button created in Xcode
Here is a link to download the entire Xcode project
WARNING: The desktop screen saver function will freeze the App. After force quit and re-open, The desktop screensaver function to exit active screen saver will work.
Afterthoughts: I probably should have wrapped each of the AppleScript codes in "try" statements to avoid all sorts of error messages for those playing with this project,who don't have the same system and computer type that I do. (MacBook Pro 15" OS Sierra 10.12.6)
For the zoom function To work, it must be enabled in system preferences.
For the toggling of “Dictation on/off” to function correctly, the short cut to enable dictation commands in system preferences must match the shortcut used in the script
on doSomething13:sender -- Dictation On/Off
tell application "System Events"
keystroke "x" using {option down}
end tell
end doSomething13:
Currently I am working on the ability to toggle between the application running windowed or menu bar only
Solution 2:
Heres how to get in the menu bar with pure AppleScript. Save as Aplication with stay open after run handler
:
P.S. I stole the code for the actual play/pause functions from @wch1zpink so please upvote their answer also
--AppleScript: menu bar script -- Created 2017-03-03 by Takaaki Naganoya adapted by Josh Brown
--2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
--http://piyocast.com/as/archives/4502
property aStatusItem : missing value
on run
init() of me
end run
on init()
set aList to {"Google Chrome", "⏯", "", "Safari", "⏯", "", "Quit"}
set aStatusItem to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:(current application's NSVariableStatusItemLength)
aStatusItem's setTitle:"🎛"
aStatusItem's setHighlightMode:true
aStatusItem's setMenu:(createMenu(aList) of me)
end init
on createMenu(aList)
set aMenu to current application's NSMenu's alloc()'s init()
set aCount to 1
repeat with i in aList
set j to contents of i
if j is not equal to "" then
set aMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:j action:"actionHandler:" keyEquivalent:"")
else
set aMenuItem to (current application's NSMenuItem's separatorItem())
end if
(aMenuItem's setTarget:me)
(aMenuItem's setTag:aCount)
(aMenu's addItem:aMenuItem)
if j is not equal to "" then
set aCount to aCount + 1
end if
end repeat
return aMenu
end createMenu
on actionHandler:sender
set aTag to tag of sender as integer
set aTitle to title of sender as string
if aTitle is "Quit" then
current application's NSStatusBar's systemStatusBar()'s removeStatusItem:aStatusItem
end if
#Chrome
if aTitle is "⏯" then
clickClassName("ytp-play-button ytp-button", 0)
end if
#Safari
if aTitle is "⏯" then
clickClassName2("ytp-play-button ytp-button", 0)
end if
end actionHandler:
to clickClassName(theClassName, elementnum)
tell application "Google Chrome" to (tabs of window 1 whose URL contains "youtube")
set youtubeTabs to item 1 of the result
tell application "Google Chrome"
execute youtubeTabs javascript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();"
end tell
end clickClassName
to clickClassName2(theClassName, elementnum)
tell application "Safari"
tell window 1 to set current tab to tab 1 whose URL contains "youtube"
do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();" in document 1
end tell
end clickClassName2