Просмотр исходного кода

Sync at most once per second.
Attempt to reconnect if we lose our state socket while playing.
Track playing state locally for faster play/pause recovery.
Only wait 1 second between updates, even if there are no new events.

Zachary Kotlarek 13 лет назад
Родитель
Сommit
d19783a188
1 измененных файлов с 49 добавлено и 30 удалено
  1. 49 30
      dmx/rifftrax.pl

+ 49 - 30
dmx/rifftrax.pl

@@ -19,12 +19,16 @@ my $RIFF_PATH      = $MEDIA_PATH . '/iTunes/iTunes Music/RiffTrax';
 my $ACTION_DELAY   = 0.1;
 my $JUMP_THRESHOLD = 5;
 
+# Prototypes
+sub playRiff();
+sub pauseRiff();
+
 # App config
 my $DATA_DIR     = DMX::dataDir();
 my $OUTPUT_FILE  = $DATA_DIR . 'RIFF';
 my $STATE_SOCK   = $OUTPUT_FILE . '.socket';
 my $PULL_TIMEOUT = 60;
-my $DELAY        = $PULL_TIMEOUT / 2;
+my $DELAY        = 1;
 my %RIFFS        = ();
 
 # Debug
@@ -106,14 +110,16 @@ DMX::stateSubscribe($STATE_SOCK);
 # State
 my $state     = 'OFF';
 my $stateLast = $state;
-my $riff      = -1;
+my $riff      = '';
 my $riffLast  = $riff;
-my $url       = '';
-my $urlLast   = $url;
+my $title     = '';
+my $titleLast = $title;
 my $nudge     = 0;
 my %exists    = ();
 my %last      = ();
 my $pullLast  = time();
+my $lastSync  = time();
+my $playing   = 0;
 
 # Loop forever
 while (1) {
@@ -123,9 +129,10 @@ while (1) {
 	$riffLast  = $riff;
 	%last      = %exists;
 
-	# Force a change if our riff is clearly invalid (first loop, reset, etc.)
-	if ($riff < 0) {
-		$riff = 0;
+	# Reconnect if we're playing and haven't seen an update for $JUMP_THRESHOLD seconds
+	if ($playing && time() - $pullLast > $JUMP_THRESHOLD) {
+		print STDERR "Attempting to reconnect state socket...\n";
+		DMX::stateSubscribe($STATE_SOCK);
 	}
 
 	# Wait for state updates
@@ -151,13 +158,13 @@ while (1) {
 
 	# Save the last URL, so we can find changes
 	# Do not delete the last URL if no new one is provided
-	if ($exists{'PLAYING_URL'}) {
-		$urlLast = $url;
-		$url     = $exists{'PLAYING_URL'};
+	if (exists($exists{'PLAYING_TITLE'})) {
+		$titleLast = $title;
+		$title     = $exists{'PLAYING_TITLE'};
 	}
 
-	# Update our state when the PLAYING_URL changes
-	if ($url ne $urlLast) {
+	# Update our state when the PLAYING_TITLE changes
+	if ($title ne $titleLast) {
 
 		# If a RIFF was active, clear it
 		if ($riff) {
@@ -171,15 +178,15 @@ while (1) {
 		}
 
 		# Activate a new RIFF, if applicable
-		if ($exists{'PLAYING_TITLE'} && exists($RIFFS{ $exists{'PLAYING_TITLE'} })) {
-			$riff = $exists{'PLAYING_TITLE'};
+		if ($RIFFS{$title}) {
+			$riff = $title;
 			if ($DEBUG) {
 				print STDERR 'Matched RIFF: ' . $riff . ' => ' . $RIFFS{$riff}->{'file'} . "\n";
 			}
 
 			Audio::addLoad('RIFF', $RIFFS{$riff}->{'path'});
-			Audio::background('RIFF');
 			Audio::rate('RIFF', $RIFFS{$riff}->{'rate'});
+			playRiff();
 			DMX::say('RiffTrax initiated');
 		}
 	}
@@ -205,20 +212,22 @@ while (1) {
 		rename($tmp, $OUTPUT_FILE);
 	}
 
-	# Sync
+	# Play/pause to match the video
+	# This assumes our local state is valid. We double-check that state tracking if the sync error is large enough to trigger a jump
 	if ($riff) {
-		if ($DEBUG) {
-			print STDERR "Syncing\n";
+		if ($state eq 'PAUSE' && $playing) {
+			pauseRiff();
+		} elsif ($state eq 'PLAY' && !$playing) {
+			playRiff();
 		}
+	}
 
-		# Play/pause to match the video
-		if ($stateLast ne $state) {
-			if ($state eq 'PAUSE') {
-				Audio::pause('RIFF');
-			} elsif ($state eq 'PLAY') {
-				Audio::background('RIFF');
-			}
+	# Sync at most once per second
+	if ($riff && $lastSync < time()) {
+		if ($DEBUG) {
+			print STDERR "Syncing\n";
 		}
+		$lastSync = time();
 
 		# Get the video and riff playback positions
 		my $rate = Audio::rate('RIFF', undef());
@@ -260,11 +269,11 @@ while (1) {
 			my $newPos = $riffTime + $error + $ACTION_DELAY;
 
 			if ($newPos < 0) {
-				Audio::pause('RIFF');
+				pauseRiff();
 			} else {
 
-				# See if we're playing
-				my $playing = Audio::playing('RIFF');
+				# Ensure our local playing state tracking is accurate
+				$playing = Audio::playing('RIFF');
 
 				# Jump if we're off by more than a few seconds
 				if ($errorAbs > $JUMP_THRESHOLD) {
@@ -295,9 +304,9 @@ while (1) {
 				# But double-check while adjusting in case things get out-of-sync
 				if (exists($exists{'PLAYING'})) {
 					if ($exists{'PLAYING'} && !$playing) {
-						Audio::background('RIFF');
+						playRiff();
 					} elsif (!$exists{'PLAYING'} && $playing) {
-						Audio::pause('RIFF');
+						pauseRiff();
 					}
 				}
 			}
@@ -310,3 +319,13 @@ while (1) {
 		}
 	}
 }
+
+sub playRiff() {
+	$playing = 1;
+	Audio::background('RIFF');
+}
+
+sub pauseRiff() {
+	$playing = 0;
+	Audio::pause('RIFF');
+}