mpv-clip 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #!/bin/bash
  2. # designed to play URLs straight from your browser
  3. # (mpv will use youtube-dl automatically) - but it should work on local files
  4. # too. use cases:
  5. # 1. if you pass the URL as first argument, it opens a smallish mpv window on
  6. # the right screen edge, and plays the video. pretty normal.
  7. # 2. if one of the first arguments is "audioonly", and the second argument is a URL,
  8. # it will still open a small window containing the time position, because
  9. # otherwise mpv would run in background and be hard to kill. the screensaver
  10. # stays enabled.
  11. # 3. if one of the first arguments is "playlist", it will ask youtbe-dl to
  12. # advance through the playlist (if appliccable) instead of stopping after the first file.
  13. # in all cases, notifications are shown for information, succes or error, and
  14. # the URL and the window title (usually the name of the track) are copied to the
  15. # clipboard.
  16. # Works well with FF's OpenWith... addon
  17. # Openbox users can add sth like this to their rc.xml:
  18. #~ <keybind key="W-y">
  19. #~ <action name="Execute">
  20. #~ <command>sh -c 'mpv-clip "$(xclip -o)"'</command>
  21. #~ </action>
  22. #~ </keybind>
  23. # Result: Highlight URL, enter W-y, enjoy!
  24. ownpid=$$
  25. fail=0
  26. audioonly=''
  27. x11name="mpv-clip" # xprop class name to be used by xdotool and optionally window manager
  28. icon="$HOME/.icons/youtube-dl*" # needs to be used without quotes later on
  29. opts="--force-window=yes --no-stop-screensaver" # mpv options for all use cases
  30. # --ytdl-format='bestvideo[height<=?1080][fps<=?30][vcodec!=?vp9]+bestaudio/best' this option (restrict video resolution *intelligently* i.e. no format not found errors) must be added to mpv.conf - doesn't work here.
  31. bbcode=0 # fill clipboard with BBcode instead of plain text
  32. # if this variable is not empty we will replace "youtube.com" and "youtu.be" with "$ytmirror"
  33. ytmirror="invidio.us"
  34. ytmirrortimeout=5 # in seconds; applied twice, for host lookup and ping
  35. if [[ "$1" != http?(s)://?(www.)* ]]; then
  36. while [[ "$1" != http?(s)://?(www.)* ]]; do
  37. case "$1" in
  38. audioonly)
  39. audioonly=" audio only"
  40. # if there's already one or several instances of audioonly running, offset the window upwards
  41. #~ offset=( $(pgrep -f 'mpv.*audioonly-mpv-clip-.*') )
  42. #~ offset=${#offset[@]}
  43. #~ geometry="220x60-0-$((64 * offset))"
  44. geometry="220x60-0-0"
  45. # no video, but persistent osd, like this: dt.iki.fi/stuff/mpv-clip-audioonly.png
  46. opts="$opts --vid=no \
  47. --sub=no --geometry=$geometry \
  48. --osd-scale-by-window=no --no-osd-bar --no-osc \
  49. --osd-msg1=\${time-pos}/\${duration}\\n\${media-title} \
  50. --osd-font-size=28 --osd-font=monospace --background=.2/.2/.2 \
  51. --osd-color=.3/.9/.9 --osd-border-size=0 \
  52. --osd-margin-y=0 --osd-margin-x=5"
  53. x11name="${x11name}-audioonly"
  54. #~ --osd-align-x=center --osd-align-y=center \
  55. # mpv can take care of window decorations, but it's nicer to let openbox do it by adding a snippet like this to the <applications> section of your rc.xml:
  56. # <application name="mpv-clip-audioonly*">
  57. # <decor>no</decor>
  58. # </application>
  59. ;;
  60. playlist)
  61. opts="$opts --ytdl-raw-options=yes-playlist="
  62. ;;
  63. 720)
  64. opts="$opts --ytdl-raw-options=format=best[height<=720]"
  65. ;;
  66. esac
  67. shift
  68. done
  69. else
  70. opts="$opts --geometry=720x405-0-50%"
  71. fi
  72. x11name="$x11name-$(date '+mpv-clip-%s')"
  73. URL="$1"
  74. if [[ "$1" != http?(s)://?(www.)* ]]; then
  75. notify-send -i $icon "ERROR" "\"$URL\" is not a valid web URL" # notify if it fails
  76. echo "ERROR - \"$URL\" is not a valid web URL" | xsel -b # xsel instead of xclip: unix.stackexchange.com/a/320487
  77. exit 1
  78. fi
  79. if [[ "$URL" == *youtu* ]] && [[ "$ytmirror" != "" ]] && host -W"$ytmirrortimeout" "$ytmirror" && ping -c1 -n -w"$ytmirrortimeout" "$ytmirror"; then
  80. # can invidio.us handle lists?
  81. #~[[ "$URL" != *"list="* ]] &&
  82. URL="${URL/youtube.com/$ytmirror}"
  83. URL="${URL/youtu.be/$ytmirror}"
  84. fi
  85. notify-send -i $icon "Trying:" "${URL#*:\/\/}"
  86. # cache values are in kB; equals 2GB
  87. # this will hopefully solve problems with long streams (or large files?)
  88. # that lose the connection to youtube after a while.
  89. (
  90. mpv --load-unsafe-playlists $opts --force-seekable=yes \
  91. --x11-name="$x11name" \
  92. --cache=yes \
  93. --no-terminal \
  94. --no-resume-playback \
  95. --watch-later-directory=/dev/null \
  96. "$URL"
  97. #~ --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.128 Safari/537.36" \
  98. # mpv rarely returns a clear 1 on failure, hence:
  99. if [[ $? != 0 ]];then
  100. notify-send -i $icon "ERROR" "$URL" # notify if it fails
  101. echo "$URL -- FAILED" | xsel -b # xsel instead of xclip: unix.stackexchange.com/a/320487
  102. kill -- -$ownpid # kill the whole process group. not very elegant.
  103. # also see stackoverflow.com/a/392155
  104. fi
  105. ) & disown
  106. sleep 3
  107. # hack. couldn't get video title directly from mpv's terminal output.
  108. title="$(timeout 30s xdotool search --sync --limit 1 --classname "$x11name" getwindowname)"
  109. if [[ "$title" != "" ]]; then
  110. title="${title%% - mpv}"
  111. notify-send -i $icon "Playing:" "$title\n${URL#*:\/\/}"
  112. [[ "$bbcode" == 1 ]] && echo "[url=$URL]$title[/url]" | xsel -b || echo "$URL --- $title" | xsel -b
  113. else
  114. echo "$URL" | xsel -b
  115. fi