diff options
Diffstat (limited to 'src/ios.m')
-rw-r--r-- | src/ios.m | 87 |
1 files changed, 85 insertions, 2 deletions
@@ -22,6 +22,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
22 | 22 | ||
23 | #include "ios.h" | 23 | #include "ios.h" |
24 | #include "app.h" | 24 | #include "app.h" |
25 | #include "audio/player.h" | ||
25 | #include "ui/command.h" | 26 | #include "ui/command.h" |
26 | #include "ui/window.h" | 27 | #include "ui/window.h" |
27 | 28 | ||
@@ -32,9 +33,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
32 | #include <SDL_syswm.h> | 33 | #include <SDL_syswm.h> |
33 | #include <SDL_timer.h> | 34 | #include <SDL_timer.h> |
34 | 35 | ||
35 | #import <UIKit/UIKit.h> | ||
36 | #import <CoreHaptics/CoreHaptics.h> | ||
37 | #import <AVFAudio/AVFAudio.h> | 36 | #import <AVFAudio/AVFAudio.h> |
37 | #import <CoreHaptics/CoreHaptics.h> | ||
38 | #import <UIKit/UIKit.h> | ||
39 | #import <MediaPlayer/MediaPlayer.h> | ||
38 | 40 | ||
39 | static iBool isSystemDarkMode_ = iFalse; | 41 | static iBool isSystemDarkMode_ = iFalse; |
40 | static iBool isPhone_ = iFalse; | 42 | static iBool isPhone_ = iFalse; |
@@ -241,6 +243,55 @@ void setupApplication_iOS(void) { | |||
241 | name:UIKeyboardWillHideNotification | 243 | name:UIKeyboardWillHideNotification |
242 | object:nil]; | 244 | object:nil]; |
243 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; | 245 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; |
246 | /* Media player remote controls. */ | ||
247 | MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter]; | ||
248 | [[commandCenter pauseCommand] addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) { | ||
249 | iPlayer *player = active_Player(); | ||
250 | if (player) { | ||
251 | setPaused_Player(player, iTrue); | ||
252 | return MPRemoteCommandHandlerStatusSuccess; | ||
253 | } | ||
254 | return MPRemoteCommandHandlerStatusCommandFailed; | ||
255 | }]; | ||
256 | [[commandCenter playCommand] addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) { | ||
257 | iPlayer *player = active_Player(); | ||
258 | if (player) { | ||
259 | if (isPaused_Player(player)) { | ||
260 | setPaused_Player(player, iFalse); | ||
261 | } | ||
262 | else { | ||
263 | start_Player(player); | ||
264 | } | ||
265 | return MPRemoteCommandHandlerStatusSuccess; | ||
266 | } | ||
267 | return MPRemoteCommandHandlerStatusCommandFailed; | ||
268 | }]; | ||
269 | [[commandCenter stopCommand] addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) { | ||
270 | iPlayer *player = active_Player(); | ||
271 | if (player) { | ||
272 | stop_Player(player); | ||
273 | return MPRemoteCommandHandlerStatusSuccess; | ||
274 | } | ||
275 | return MPRemoteCommandHandlerStatusCommandFailed; | ||
276 | }]; | ||
277 | [[commandCenter togglePlayPauseCommand] addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) { | ||
278 | iPlayer *player = active_Player(); | ||
279 | if (player) { | ||
280 | setPaused_Player(player, !isPaused_Player(player)); | ||
281 | return MPRemoteCommandHandlerStatusSuccess; | ||
282 | } | ||
283 | return MPRemoteCommandHandlerStatusCommandFailed; | ||
284 | }]; | ||
285 | [[commandCenter nextTrackCommand] setEnabled:NO]; | ||
286 | [[commandCenter previousTrackCommand] setEnabled:NO]; | ||
287 | [[commandCenter changeRepeatModeCommand] setEnabled:NO]; | ||
288 | [[commandCenter changeShuffleModeCommand] setEnabled:NO]; | ||
289 | [[commandCenter changePlaybackRateCommand] setEnabled:NO]; | ||
290 | [[commandCenter seekForwardCommand] setEnabled:NO]; | ||
291 | [[commandCenter seekBackwardCommand] setEnabled:NO]; | ||
292 | [[commandCenter skipForwardCommand] setEnabled:NO]; | ||
293 | [[commandCenter skipBackwardCommand] setEnabled:NO]; | ||
294 | [[commandCenter changePlaybackPositionCommand] setEnabled:NO]; | ||
244 | } | 295 | } |
245 | 296 | ||
246 | static iBool isDarkMode_(iWindow *window) { | 297 | static iBool isDarkMode_(iWindow *window) { |
@@ -335,6 +386,38 @@ iBool processEvent_iOS(const SDL_Event *ev) { | |||
335 | return iFalse; /* allow normal processing */ | 386 | return iFalse; /* allow normal processing */ |
336 | } | 387 | } |
337 | 388 | ||
389 | void updateNowPlayingInfo_iOS(void) { | ||
390 | const iPlayer *player = active_Player(); | ||
391 | if (!player) { | ||
392 | clearNowPlayingInfo_iOS(); | ||
393 | return; | ||
394 | } | ||
395 | NSMutableDictionary<NSString *, id> *info = [[NSMutableDictionary<NSString *, id> alloc] init]; | ||
396 | [info setObject:[NSNumber numberWithDouble:time_Player(player)] | ||
397 | forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; | ||
398 | [info setObject:[NSNumber numberWithInt:MPNowPlayingInfoMediaTypeAudio] | ||
399 | forKey:MPNowPlayingInfoPropertyMediaType]; | ||
400 | [info setObject:[NSNumber numberWithDouble:duration_Player(player)] | ||
401 | forKey:MPMediaItemPropertyPlaybackDuration]; | ||
402 | const iString *title = tag_Player(player, title_PlayerTag); | ||
403 | const iString *artist = tag_Player(player, artist_PlayerTag); | ||
404 | if (isEmpty_String(title)) { | ||
405 | title = collectNewCStr_String("Audio"); /* TODO: Use link label or URL file name */ | ||
406 | } | ||
407 | if (isEmpty_String(artist)) { | ||
408 | artist = collectNewCStr_String("Lagrange"); /* TODO: Use domain or base URL */ | ||
409 | } | ||
410 | [info setObject:[NSString stringWithUTF8String:cstr_String(title)] | ||
411 | forKey:MPMediaItemPropertyTitle]; | ||
412 | [info setObject:[NSString stringWithUTF8String:cstr_String(artist)] | ||
413 | forKey:MPMediaItemPropertyArtist]; | ||
414 | [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:info]; | ||
415 | } | ||
416 | |||
417 | void clearNowPlayingInfo_iOS(void) { | ||
418 | [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:nil]; | ||
419 | } | ||
420 | |||
338 | void exportDownloadedFile_iOS(const iString *path) { | 421 | void exportDownloadedFile_iOS(const iString *path) { |
339 | NSURL *url = [NSURL fileURLWithPath:[[NSString alloc] initWithCString:cstr_String(path) | 422 | NSURL *url = [NSURL fileURLWithPath:[[NSString alloc] initWithCString:cstr_String(path) |
340 | encoding:NSUTF8StringEncoding]]; | 423 | encoding:NSUTF8StringEncoding]]; |