rifftrax.pl 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use File::Temp qw( tempfile );
  5. use Time::HiRes qw( usleep sleep time );
  6. use IPC::System::Simple qw( system capture );
  7. # Local modules
  8. use Cwd qw(abs_path);
  9. use File::Basename qw(dirname);
  10. use lib dirname(abs_path($0));
  11. use DMX;
  12. use Audio;
  13. # Config
  14. my $RIFF_PATH = `~/bin/video/mediaPath` . '/iTunes/iTunes Music/RiffTrax';
  15. my %RIFFS = (
  16. 'Harry Potter 1' => {
  17. 'file' => 'Harry Potter/Harry Potter 1_ The Sorcerer\'s Stone.mp3',
  18. 'part' => '82481',
  19. 'offset' => 100,
  20. },
  21. 'Harry Potter 2' => {
  22. 'file' => 'Harry Potter/Harry Potter 2_ The Chamber of Secrets.mp3',
  23. 'part' => '82469',
  24. 'offset' => 100,
  25. }
  26. );
  27. # App config
  28. my $DATA_DIR = DMX::dataDir();
  29. my $OUTPUT_FILE = $DATA_DIR . 'RIFF';
  30. my $STATE_SOCK = $OUTPUT_FILE . '.socket';
  31. my $PULL_TIMEOUT = 60;
  32. my $DELAY = $PULL_TIMEOUT / 2;
  33. # Prototypes
  34. sub runApplescript($);
  35. # Debug
  36. my $DEBUG = 0;
  37. if ($ENV{'DEBUG'}) {
  38. $DEBUG = 1;
  39. }
  40. # Sockets
  41. DMX::stateSocket($STATE_SOCK);
  42. DMX::stateSubscribe($STATE_SOCK);
  43. # State
  44. my $RIFF = undef();
  45. my %exists = ();
  46. my $pullLast = time();
  47. # Validate our riff files at launch
  48. foreach my $riff (keys(%RIFFS)) {
  49. if ($RIFFS{$riff}{'file'} =~ /^\//) {
  50. $RIFFS{$riff}{'path'} = $RIFFS{$riff}{'file'};
  51. } else {
  52. $RIFFS{$riff}{'path'} = $RIFF_PATH . '/' . $RIFFS{$riff}{'file'};
  53. }
  54. if (!-r $RIFFS{$riff}{'path'}) {
  55. die('Invalid riff file: ' . $riff . ' => ' . $RIFFS{$riff}{'path'} . "\n");
  56. }
  57. }
  58. # Loop forever
  59. while (1) {
  60. # If the color profile has changed, save the state to disk
  61. #if ($colorLast ne $color) {
  62. # if ($DEBUG) {
  63. # print STDERR 'New color profile: ' . $colorLast . ' => ' . $color . "\n";
  64. # }
  65. # my ($fh, $tmp) = tempfile($OUTPUT_FILE . '.XXXXXXXX', 'UNLINK' => 0);
  66. # print $fh $color . "\n";
  67. # close($fh);
  68. # rename($tmp, $OUTPUT_FILE);
  69. #}
  70. # State is calculated; use newState to gather data
  71. my $newState = $state;
  72. # Wait for state updates
  73. my $cmdState = DMX::readState($DELAY, \%exists, undef(), undef());
  74. if (defined($cmdState)) {
  75. $newState = $cmdState;
  76. $pullLast = time();
  77. }
  78. # Die if we don't see regular updates
  79. if (time() - $pullLast > $PULL_TIMEOUT) {
  80. die('No update on state socket in past ' . $PULL_TIMEOUT . " seconds. Exiting...\n");
  81. }
  82. # Launch riffs when the underlying media is active
  83. if (!$RIFF && $cmdState eq 'PLAY') {
  84. my %tmp = ();
  85. $tmp{'url'} = $exists{'PLAYING_URL'};
  86. $RIFF = \%tmp;
  87. }
  88. # Close riffs when the underlying media stops
  89. if ($RIFF && $exists{'PLAYING_URL'} ne $RIFF->{'url'}) {
  90. $RIFF = undef();
  91. }
  92. }