I want to add the default emblem to videos I've finished watching. Any straightforward, non-manual way to run a script if and exactly if a video has finished playing? Can be for any linux (mint/ubuntu) video player.
2 Answers
vlc --play-and-exit video.mp4 && echo "Terminated"
Substitute echo "Terminated"
with the actual command you want to run. The &&
means that if vlc exits with an error code, the command will not be executed. If you want the command to execute even if an error happens,
vlc --play-and-exit video.mp4; echo "Terminated"
If you supply more files to vlc, then the command will only be executed once all media has been played. For example,
vlc --play-and-exit s0.mp3 s1.mp4 && shutdown now
means the system will shutdown immediately after the two files have been played.
If you want to perform an action for each file played, you can use this shell script (let's call it play.sh
):
#!/bin/sh
for file in "$@"; do
vlc --play-and-exit "$file"
echo "File $file has been played."
done
Then execute it on various files:
sh play.sh file1.mp3 'Me & You.mp4' 'file 3.wav'
Don't forget to quote the files when appropriate (especially on whitespace and special characters such as &
, *
, etc.).
The --play-and-exit
flag is also available for cvlc
.
Since I asked, I thought I'd share the quick wrapper-based hack I came up with that does it.
I've created the following vlc wrapper and set up video files to open in it rather than vlc directly. It only supports one file at a time. If the thing that moves in vlc as it plays a file goes all the way up to the end, it will run the tag watched
command at the end if about 60% of the video has been watched.
#!/bin/bash
#This depends on the cli interface having been activated in the preferences
# This while loop feeds the `get_length` vlc cli command to cli every 0.1 s
(while :; do echo get_length; sleep 0.1 ; done) |
#Pass all arguments to vlc and set it up to be fed from the `get_length` while loop
/usr/bin/vlc "$@" |
ruby -n -e '
BEGIN {
cons_empty=0
nlines_read=0
}
#Strip vlc cli noise
$_=$_.sub(/^[> ]*/,"")
#Watch consecutive (cons) empty lines
if $_.match(/^\s*$/)
cons_empty += 1
else
#Assume each nonempty stdin line is the duration
duration = $_.chomp.to_i
cons_empty = 0
nlines_read += 1
end
#On 10 consecutive empty lines, assume the file has finished playing
if cons_empty == 10
time_watched = nlines_read * 0.1
p time_watched: time_watched, duration: duration
ret = (time_watched > 0.6 * duration) ? 1 : 0
exit ret
end
' ||
tag watched "$@" #1 exit means finished watching
It's working rather than beautiful code, but it's only a quick fix for an annoyance.
Dependencies:
bash, ruby, + replace tag watched
with your actual tagging command.
not playing
image from vlc-media-player