annotate osx/svitunes.mm @ 383:abb9c3dedec2 macness

ITunesSVRemote methods to query playback position and state
author Dan Stowell <dan.stowell@eecs.qmul.ac.uk>
date Mon, 18 Oct 2010 14:44:28 +0100
parents fad5611ef9db
children be237d380f5f
rev   line source
dan@367 1 /*
dan@367 2 iTunes connection for
dan@367 3 Sonic Visualiser
dan@367 4 An audio file viewer and annotation editor.
dan@367 5 Centre for Digital Music, Queen Mary, University of London.
dan@367 6 This file copyright 2010 Dan Stowell and QMUL.
dan@367 7
dan@367 8 This program is free software; you can redistribute it and/or
dan@367 9 modify it under the terms of the GNU General Public License as
dan@367 10 published by the Free Software Foundation; either version 2 of the
dan@367 11 License, or (at your option) any later version. See the file
dan@367 12 COPYING included with this distribution for more information.
dan@367 13 */
dan@367 14
dan@367 15 #include "svitunes.h"
dan@367 16
dan@367 17 #include <Foundation/NSAppleScript.h>
dan@367 18
dan@367 19 #import <Foundation/Foundation.h>
dan@367 20
dan@383 21 #include <iostream>
dan@383 22 #include <cstdio>
dan@383 23
dan@383 24 // private helpful function:
dan@367 25 QString qt_mac_NSStringToQString(const NSString *nsstr)
dan@367 26 {
dan@367 27 NSRange range;
dan@367 28 range.location = 0;
dan@367 29 range.length = [nsstr length];
dan@367 30
dan@367 31 unichar *chars = new unichar[range.length + 1];
dan@367 32 chars[range.length] = 0;
dan@367 33 [nsstr getCharacters:chars range:range];
dan@367 34 QString result = QString::fromUtf16(chars, range.length);
dan@367 35 delete chars;
dan@367 36 return result;
dan@367 37 }
dan@367 38
dan@381 39 QStringList ITunesSVRemote::getNowPlaying(){
dan@367 40 NSDictionary *errorDict;
dan@367 41 NSAppleScript *scriptObject = [[NSAppleScript alloc] initWithSource:@" \
dan@367 42 tell application \"System Events\" to set iTunesIsRunning to (name of processes) contains \"iTunes\" \n\
dan@367 43 if iTunesIsRunning is false then return \"\" \n\
dan@368 44 \
dan@368 45 tell application \"iTunes\" \n\
dan@368 46 if player state is not stopped then \n\
dan@368 47 set aTrack to current track \n\
dan@368 48 else \n\
dan@368 49 set sel to selection \n\
dan@368 50 if sel is not {} then --and (length of sel) is 1 then \n\
dan@368 51 set aTrack to item 1 of sel \n\
dan@368 52 else \n\
dan@368 53 return \"\" \n\
dan@368 54 end if \n\
dan@368 55 end if \n\
dan@368 56 \
dan@370 57 return the POSIX path of (location of aTrack as text) & \"\n\" & (genre of aTrack) \n\
dan@368 58 end tell \n\
dan@368 59 "
dan@367 60 ];
dan@367 61
dan@367 62 NSLog([scriptObject source]);
dan@367 63
dan@367 64 [scriptObject compileAndReturnError: &errorDict];
dan@367 65
dan@367 66 if(![scriptObject isCompiled]){
dan@367 67 NSLog(@"SV ERROR: applescript object not compiled");
dan@367 68 NSLog([errorDict description]);
dan@367 69 }
dan@367 70
dan@367 71 NSAppleEventDescriptor *eventDesc = [scriptObject executeAndReturnError: &errorDict];
dan@367 72 NSString *nsResultString = [eventDesc stringValue];
dan@367 73
dan@367 74 QString resultString = qt_mac_NSStringToQString(nsResultString);
dan@367 75
dan@367 76 [scriptObject release];
dan@370 77 return resultString.split(QChar('\n'));
dan@367 78 }
dan@383 79
dan@383 80 void ITunesSVRemote::updatePlayerState(){
dan@383 81 NSDictionary *errorDict;
dan@383 82 NSAppleScript *scriptObject = [[NSAppleScript alloc] initWithSource:@" \
dan@383 83 tell application \"System Events\" to set iTunesIsRunning to (name of processes) contains \"iTunes\" \n\
dan@383 84 if iTunesIsRunning is false then return \"\" \n\
dan@383 85 \
dan@383 86 tell application \"iTunes\" \n\
dan@383 87 if player state is not playing then \n\
dan@383 88 set playpos to 0 \n\
dan@383 89 else \n\
dan@383 90 set playpos to player position \n\
dan@383 91 end if \n\
dan@383 92 \
dan@383 93 return (player state as text) & \"\n\" & (playpos) \n\
dan@383 94 end tell \n\
dan@383 95 "
dan@383 96 ];
dan@383 97
dan@383 98 NSLog([scriptObject source]);
dan@383 99
dan@383 100 [scriptObject compileAndReturnError: &errorDict];
dan@383 101
dan@383 102 if(![scriptObject isCompiled]){
dan@383 103 NSLog(@"SV ERROR: applescript object not compiled");
dan@383 104 NSLog([errorDict description]);
dan@383 105 }
dan@383 106
dan@383 107 NSAppleEventDescriptor *eventDesc = [scriptObject executeAndReturnError: &errorDict];
dan@383 108 NSString *nsResultString = [eventDesc stringValue];
dan@383 109
dan@383 110 QString resultString = qt_mac_NSStringToQString(nsResultString);
dan@383 111
dan@383 112 if(resultString==""){
dan@383 113 m_playerState = STATE_CLOSED;
dan@383 114 std::cerr << "ITunesSVRemote::updatePlayerState() IT IS CLOSED" << std::endl;
dan@383 115 }else{
dan@383 116 QStringList results = resultString.split(QChar('\n'));
dan@383 117
dan@383 118 if(results.size() != 2){
dan@383 119 std::cerr << "ITunesSVRemote::updatePlayerState() ERROR: results not in expected format:"
dan@383 120 << resultString.toStdString() << std::endl;
dan@383 121 [scriptObject release];
dan@383 122 return;
dan@383 123 }
dan@383 124
dan@383 125 if(results[0]=="playing")
dan@383 126 m_playerState = STATE_PLAYING;
dan@383 127 else if(results[0]=="paused")
dan@383 128 m_playerState = STATE_PAUSED;
dan@383 129 else if(results[0]=="stopped")
dan@383 130 m_playerState = STATE_STOPPED;
dan@383 131 else if(results[0]=="fast forwarding")
dan@383 132 m_playerState = STATE_FASTFORWARDING;
dan@383 133 else if(results[0]=="rewinding")
dan@383 134 m_playerState = STATE_REWINDING;
dan@383 135
dan@383 136 if(m_playerState == STATE_PLAYING){
dan@383 137 // store a record of the current playback position
dan@383 138 m_playerPos = results[1].toInt();
dan@383 139 std::cerr << "ITunesSVRemote::updatePlayerState() got playback position as "
dan@383 140 << m_playerPos << std::endl;
dan@383 141 }
dan@383 142 }
dan@383 143
dan@383 144 [scriptObject release];
dan@383 145 }
dan@383 146
dan@383 147 bool ITunesSVRemote::isRunning(){
dan@383 148 return (m_playerState != STATE_UNKNOWN) && (m_playerState != STATE_CLOSED);
dan@383 149 }
dan@383 150
dan@383 151 bool ITunesSVRemote::isPlaying(){
dan@383 152 return (m_playerState == STATE_PLAYING);
dan@383 153 }
dan@383 154
dan@383 155 unsigned int ITunesSVRemote::playerPos(){
dan@383 156 return m_playerPos;
dan@383 157 }