Skip to content

Instantly share code, notes, and snippets.

@danielrotaermel
Last active December 8, 2023 22:31
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save danielrotaermel/201f549d5755ea886eb78bb660133722 to your computer and use it in GitHub Desktop.
Save danielrotaermel/201f549d5755ea886eb78bb660133722 to your computer and use it in GitHub Desktop.
Applescript to toggle picture-in-picture globally - I assign this to a keyboard shortcut with better touch tool (cmd+ctrl+p). Make sure "Developer > Allow JavaScript from Apple Events" is enabled in Safari. Download BTT preset -> https://share.folivora.ai/sharedPreset/caa1198d-36dd-4aeb-89de-142bf39cc336
(*
Description: Applescript to open/close picture-in-picture in Safari
Supported Applications: Safari, IINA
Author: Daniel Rotärmel
Source: https://gist.github.com/danielrotaermel/201f549d5755ea886eb78bb660133722
Instructions:
Assign this to a global keyboard shortcut with better touch tool / hammerspoon etc. - suggested: cmd+ctrl+p.
Make sure "Developer > Allow JavaScript from Apple Events" is enabled in Safari.
Download the BTT preset here -> https://share.folivora.ai/sharedPreset/caa1198d-36dd-4aeb-89de-142bf39cc336
*)
set jsStartPip to "document.querySelector('video').webkitSetPresentationMode('picture-in-picture')"
set jsVideoExistsAndInline to "if (document.querySelector('video')!== null) document.querySelector('video').webkitPresentationMode === 'inline' ? true : false; else false;"
on closePip()
tell application "System Events"
if exists (window 1 of process "PIPAgent") then
-- display dialog "Found window 1"
-- get every UI element of (window 1 of process "PIPAgent")
click button 3 of (window 1 of process "PIPAgent")
-- click button 1 of (window 1 of process "PIPAgent")
end if
end tell
end closePip
-- tell application "Safari" to activate
-- tell application "IINA" to activate
tell application "System Events" to set frontApp to name of first process whose frontmost is true
if frontApp = "Safari" then
tell application "Safari"
set isVideoInline to do JavaScript jsVideoExistsAndInline in front document
if isVideoInline then
do JavaScript jsStartPip in front document
else
tell application "System Events"
if exists (window 1 of process "PIPAgent") then
-- display dialog "Found window 1"
-- get every UI element of (window 1 of process "PIPAgent")
click button 3 of (window 1 of process "PIPAgent")
-- click button 1 of (window 1 of process "PIPAgent")
end if
end tell
end if
end tell
else if (frontApp = "IINA") then
tell application "System Events"
tell process "IINA"
try
click menu item "Enter Picture-in-Picture" of menu "Video" of menu bar 1
on error
click menu item "Exit Picture-in-Picture" of menu "Video" of menu bar 1
end try
end tell
end tell
else
closePip()
end if
@kittylotus
Copy link

Hey,
I tried this but it doesn't work even with "Developer > Allow JavaScript from Apple Events" what am I missing?

@danielrotaermel
Copy link
Author

Hey, have you tried running it from Script Editor?

@danielrotaermel
Copy link
Author

Hey 👋🏻, to get it running in Automator create a „Quick Action“ then add the apple script. Make sure that the workflow receives „no input“ in „any application“ and save it as „PiP“. In system Settings > Keyboard > Shortcuts > App Shortcuts create a shortcut for „All Applications“, Menu: „PiP“ and map a keyboard shortcut. That should be it. Now the shortcut will toggle PiP.
Maybe there will be some permission errors but I don‘t remember those. Let me know if you run into any problems

@alanmicah
Copy link

alanmicah commented May 17, 2022

Hi, when pressing the shortcut whilst playing a video on YouTube in Safari I'm getting an error with "The variable isVideoInline is not defined". I'm running on an M1 based MacBook Safari 15.5

@danielrotaermel
Copy link
Author

Hi @doseofding, I am using Safari 15.3 so I don’t think that’s an issue. I really can’t really think of why the variable wouldn’t be defined. Are you using the btt preset or automator to trigger the apple script?

Maybe you can debug the apple script from script editor just make sure to uncomment line 27 for that, so it activates safari beforehand.

@alanmicah
Copy link

@danielrotaermel I'm using Automator to trigger the apple script as a Quick Action.

@mkozjak
Copy link

mkozjak commented Aug 20, 2023

This does not work on Ventura anymore since isVideoInline is undefined. Seems like the jsVideoExistsAndInline cannot be set as the procedure doesn't return a value. Do JavaScript seems to expect certain types of values to return. I'm still puzzled on what works.

@danielrotaermel
Copy link
Author

I am still running Monterey. Once I‘ll update I can try to debug.

@mkozjak
Copy link

mkozjak commented Oct 6, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment