Ver Fonte

LEADIN support

Zachary Kotlarek há 13 anos atrás
pai
commit
fe14e3bcd9
1 ficheiros alterados com 81 adições e 20 exclusões
  1. 81 20
      dmx/rifftrax.pl

+ 81 - 20
dmx/rifftrax.pl

@@ -17,6 +17,7 @@ my $MEDIA_PATH     = `~/bin/video/mediaPath`;
 my $CONFIG_PATH    = $MEDIA_PATH . '/DMX/RiffTrax';
 my $CONFIG_PATH    = $MEDIA_PATH . '/DMX/RiffTrax';
 my $ACTION_DELAY   = 0.1;
 my $ACTION_DELAY   = 0.1;
 my $JUMP_THRESHOLD = 5;
 my $JUMP_THRESHOLD = 5;
+my $LEADIN_TIME    = 5;
 my $VOLUME_RIFF    = 65;
 my $VOLUME_RIFF    = 65;
 my $VOLUME_STD     = 40;
 my $VOLUME_STD     = 40;
 my $VOL_STEP       = 1 / 20;
 my $VOL_STEP       = 1 / 20;
@@ -28,6 +29,7 @@ sub pauseRiff();
 sub getRiffRate();
 sub getRiffRate();
 sub setRiffRate($);
 sub setRiffRate($);
 sub parseConfig($$);
 sub parseConfig($$);
+sub playPausePlex();
 
 
 # App config
 # App config
 my $DATA_DIR     = DMX::dataDir();
 my $DATA_DIR     = DMX::dataDir();
@@ -60,6 +62,7 @@ my $pullLast  = time();
 my $lastSync  = time();
 my $lastSync  = time();
 my $playing   = 0;
 my $playing   = 0;
 my $delay     = $DELAY;
 my $delay     = $DELAY;
+my $leadin    = 0;
 
 
 # Read the config
 # Read the config
 parseConfig($CONFIG_PATH, \%RIFFS);
 parseConfig($CONFIG_PATH, \%RIFFS);
@@ -138,6 +141,20 @@ while (1) {
 		$title     = $exists{'PLAYING_TITLE'};
 		$title     = $exists{'PLAYING_TITLE'};
 	}
 	}
 
 
+	# Convert the video timestamp to seconds
+	my $videoTime = 0;
+	if ($exists{'PLAYING_POSITION'}) {
+		my @parts = split(/\:/, $exists{'PLAYING_POSITION'});
+		$videoTime = 0;
+		if (scalar(@parts) == 3) {
+			$videoTime = ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
+		} elsif (scalar(@parts) == 2) {
+			$videoTime = ($parts[0] * 60) + $parts[1];
+		} else {
+			$videoTime = $parts[0];
+		}
+	}
+
 	# Update our state when the PLAYING_TITLE changes
 	# Update our state when the PLAYING_TITLE changes
 	if ($title ne $titleLast) {
 	if ($title ne $titleLast) {
 
 
@@ -155,7 +172,8 @@ while (1) {
 
 
 			# Close the audio file
 			# Close the audio file
 			Audio::unload('RIFF');
 			Audio::unload('RIFF');
-			$riff = 0;
+			$riff   = 0;
+			$leadin = 0;
 
 
 			# Warm fuzzies
 			# Warm fuzzies
 			DMX::say('RiffTrax complete');
 			DMX::say('RiffTrax complete');
@@ -185,6 +203,12 @@ while (1) {
 
 
 			# Reduce the delay while playing so we sync faster
 			# Reduce the delay while playing so we sync faster
 			$delay = 1;
 			$delay = 1;
+
+			# Enable LEADIN if we're near the beginning of the movie
+			if ($RIFFS{$riff}->{'offset'} > $LEADIN_TIME && $videoTime < $LEADIN_TIME) {
+				playPausePlex();
+				$leadin = 1;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -209,15 +233,29 @@ while (1) {
 		rename($tmp, $OUTPUT_FILE);
 		rename($tmp, $OUTPUT_FILE);
 	}
 	}
 
 
-	# Play/pause to match the video state
-	if ($riff && exists($exists{'PLAYING'})) {
-		if (!$exists{'PLAYING'} && $playing) {
+	# Skip further processing if we don't have valid state data from Plex
+	if (!exists($exists{'PLAYING'})) {
+		next;
+	}
+
+	# Play/pause to match the video or LEADIN state
+	if ($riff) {
+		if ($leadin) {
+			if (!$playing) {
+				playRiff();
+			}
+		} elsif (!$exists{'PLAYING'} && $playing) {
 			pauseRiff();
 			pauseRiff();
 		} elsif ($exists{'PLAYING'} && !$playing) {
 		} elsif ($exists{'PLAYING'} && !$playing) {
 			playRiff();
 			playRiff();
 		}
 		}
 	}
 	}
 
 
+	# Skip further processing if we don't have valid sync data from Plex
+	if (!$videoTime) {
+		next;
+	}
+
 	# Sync at most once per second
 	# Sync at most once per second
 	if ($riff && $lastSync < time()) {
 	if ($riff && $lastSync < time()) {
 		if ($DEBUG) {
 		if ($DEBUG) {
@@ -225,10 +263,9 @@ while (1) {
 		}
 		}
 		$lastSync = time();
 		$lastSync = time();
 
 
-		# Get the video and riff playback positions
-		my $rate      = getRiffRate();
-		my $riffTime  = Audio::position('RIFF', undef());
-		my $videoTime = $exists{'PLAYING_POSITION'};
+		# Get the riff playback state
+		my $rate = getRiffRate();
+		my $riffTime = Audio::position('RIFF', undef());
 
 
 		# Update our local playing state tracker
 		# Update our local playing state tracker
 		# The rate is always 0 when paused (Audio::playing uses this same methodology)
 		# The rate is always 0 when paused (Audio::playing uses this same methodology)
@@ -238,17 +275,6 @@ while (1) {
 			$playing = 0;
 			$playing = 0;
 		}
 		}
 
 
-		# Convert the timestamp to seconds
-		my @parts = split(/\:/, $videoTime);
-		$videoTime = 0;
-		if (scalar(@parts) == 3) {
-			$videoTime = ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
-		} elsif (scalar(@parts) == 2) {
-			$videoTime = ($parts[0] * 60) + $parts[1];
-		} else {
-			$videoTime = $parts[0];
-		}
-
 		# Calculate the adjusted riff time and the error between the riff and video times
 		# Calculate the adjusted riff time and the error between the riff and video times
 		my $riffAdjTime = $riffTime - $RIFFS{$riff}->{'offset'};
 		my $riffAdjTime = $riffTime - $RIFFS{$riff}->{'offset'};
 		my $error       = $videoTime - $riffAdjTime;
 		my $error       = $videoTime - $riffAdjTime;
@@ -262,9 +288,38 @@ while (1) {
 			print STDERR "\tVideo time: " . $videoTime . "\n";
 			print STDERR "\tVideo time: " . $videoTime . "\n";
 			print STDERR "\tAdjusted riff time: " . $riffAdjTime . "\n";
 			print STDERR "\tAdjusted riff time: " . $riffAdjTime . "\n";
 			print STDERR "\tError: " . $error . "\n";
 			print STDERR "\tError: " . $error . "\n";
+			print STDERR "\tLeadin: " . $leadin . "\n";
 		}
 		}
 
 
-		# Adjust the riff position if we're off by 0.5 seconds or more
+		# If LEADIN is still active
+		if ($leadin) {
+
+			# Deactivate LEADIN if the movie advances outside the LEADIN_TIME window
+			if ($videoTime > $LEADIN_TIME) {
+				$leadin = 0;
+				if ($DEBUG) {
+					print STDERR "LEADIN canceled due to video time\n";
+				}
+			}
+
+			# Start the movie when we reach the sync point
+			if ($RIFFS{$riff}->{'offset'} <= $riffTime) {
+				if (!$exists{'PLAYING'}) {
+					playPausePlex();
+				}
+				$leadin = 0;
+				if ($DEBUG) {
+					print STDERR "LEADIN canceled due to synchronization\n";
+				}
+			}
+
+			# Skip normal syncing until LEADIN is cleared
+			if ($leadin) {
+				next;
+			}
+		}
+
+		# Adjust the riff rate/position if we're off by 0.5 seconds or more
 		if ($errorAbs > 0.5) {
 		if ($errorAbs > 0.5) {
 
 
 			# Calculate the new position, including an ACTION_DELAY adjustment to compensate for time elapsed in this process
 			# Calculate the new position, including an ACTION_DELAY adjustment to compensate for time elapsed in this process
@@ -425,3 +480,9 @@ sub parseConfig($$) {
 	# Record the last update time
 	# Record the last update time
 	$riffs->{'_LAST_CONFIG_UPDATE'} = time();
 	$riffs->{'_LAST_CONFIG_UPDATE'} = time();
 }
 }
+
+# The UDP listener would be more portable, but I already know how to do this
+# The PMS playback API would work too, but this script currently knows nothing of the PMS
+sub playPausePlex() {
+	Audio::runApplescript('tell application "System Events" to key code 49');
+}