Le risposte alle domande sul MacLe domande sul Mac

Keep disk awake for VLC playing - v. 3

Main topics: ResourcesMacDownload

Argomenti: DischiUtilityOpensourceTerminaleMac OS 64bit

Author: Marco Balestra

VLC hanging during play?

The scenario is quite common:

  • A Mac running Ventura (or earlier) Mac OS
  • An external disk (let’s say USB) connected
  • VLC playing a movie stored on such disk

In this case it could happen that disk goes to sleep (this normally happens after 10 seconds without access) and the movie freezes a few seconds while the disk respins for buffering.

Workarounds…

  • A first solution is “copy the file on your HD and play it from there".
    But I wanted to play my files on their disk, without copies.
  • Another solution could be caffeine app
    But in this case the Mac would stay awake forever, while want to keep my Mac (and my disk) awake if and only if VLC is playing, and only for the involved disk, without any further action.

My solution (v. 3)

The solution is a simple script that will run indefinitely:

  • checking every 5 seconds if VLC is running and is playing a movie
  • else checking every 30 seconds for VLC playing:
    • checks if VLC is running, if true…
    • checks if VLC in playing, if true…
    • Asks VLC for movie path and sets refresh time to 5 seconds
  • in case VLC is playing (every 5 seconds) performs a read access to movie’s disk root to keep it awake

You can download the script, unzip it, go to its folder with Terminal and run the command: ./keepDiskAwakeForVlcPlaying install

The script is copied in /usr/local/bin/keepDiskAwakeForVlcPlaying and added to Login Items.

When first VLC playing event occurs while the script is running you’ll be asked to give “perl” the permission to interact with VLC.
Of course say yes.

Here follow both the script (compressed) and its source, if you want to do it on your own.

.zip

The source

In case you decide to create the script from source, don’t forget to make it executable.

The script includes the installer.

#!/usr/bin/perl # time expressed in seconds use constant INTERVAL_ON_IDLE => 30; use constant INTERVAL_RUNNING => 5; # internal constants use constant VERSION => 3; use constant PUBLICNAME => 'keepDiskAwakeForVlcPlaying'; use constant EXECPATH => '/usr/local/bin/'.PUBLICNAME(); use constant BUNDLEID => 'com.faqintosh.'.PUBLICNAME(); my $currentScript = "$0"; my $arg = lc(shift(@ARGV)||""); if ( $arg) { my $exit = 1; if ( $arg eq 'install' or $arg eq '-i' ) { makeExecutable(); installAtLogin(); } elsif ( $arg eq 'binary' or $arg eq '-b' ) { makeExecutable(); } elsif ( $arg eq 'version') { print PUBLICNAME()." Version: ".VERSION()."\n"; } elsif ( $arg eq '-v' ) { print VERSION()."\n"; } elsif ( $arg eq 'demonize' or $arg eq '-d' ) { while (1) { sleep( checkAwake() ? INTERVAL_RUNNING() : INTERVAL_ON_IDLE() ); } } else { $exit = 0; } exit 0 if $exit; } print STDERR <<"ENDOFHELP"; Syntax: $currentScript <param> Where <param> is one of: [LONG] [SHORT] install -i Makes binary (if needed) and installs at Login binary -b Simply makes binary file (if needed) version -v Script version (current: @{[VERSION]}) demonize -d Launch and check for VLC playing to keep disk awake Binary file is copied to @{[EXECPATH]} Needs an admin password to be created. ENDOFHELP exit 1; sub isPlaying { my $out = `ps aux | grep /VLC.app/Contents/ | grep -v grep`; chomp $out; return 0 unless $out; $out = `/usr/bin/osascript -e 'tell application "VLC" to get playing'`; chomp $out; return 0 if $out ne 'true'; $out = `/usr/bin/osascript -e 'tell application "VLC" to get path of current item'`; chomp $out; return $out; } sub checkAwake { my $file = isPlaying(); return 0 unless $file; if ( $file =~ m,^(/Volumes/[^/]+).+$, ) { my $dir = "$1"; opendir(my $dh,$dir); my @content = readdir($dh); closedir($dh); return 1; } return 0; } sub makeExecutable { my $path = EXECPATH(); if ( -x $path ) { my $hasVersion = `grep VERSION "$path"`; chomp $hasVersion; my $v = $hasVersion ? `"$path" -v` : 1; chomp $v; my $cv = VERSION(); if ( $v ) { if ( $v >= $cv ) { print "Already installed version $v (current: $cv)\n"; return; } print "Outdated version $v installed (current: $cv)\n"; } } print "Copying to: $path - Provide password and give access permission if required\n"; `sudo cp -rf "$currentScript" "$path"`; return; } sub installAtLogin { my $home = `cd; pwd`; chomp $home; my $path = "$home/Library/LaunchAgents/".BUNDLEID().".plist"; `rm -f "$path"` if ( -s $path); print "Installing Login Item: $path\n"; open(my $fh,">",$path) or die $!; print $fh <<"ENDOFLAUNCHERPLIST"; <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>@{[BUNDLEID]}</string> <key>ProgramArguments</key> <array> <string>@{[EXECPATH]}</string> <string>demonize</string> </array> <key>LimitLoadToSessionType</key> <string>Aqua</string> <key>Nice</key> <integer>10</integer> <key>RunAtLoad</key> <true/> <key>LaunchOnlyOnce</key> <true/> <key>StandardErrorPath</key> <string>/dev/null</string> <key>StandardOutPath</key> <string>/dev/null</string> </dict> </plist> ENDOFLAUNCHERPLIST close($fh); print "Install complete, active on next login.\n"; }
Powered by JBLOUD, © 2021 altersoftware.IT