在 MacO 中设置媒体播放信息不起作用

Setting media playback info in MacOs not working

我是 ObjC 和 MacOs 开发的新手。 我的最终目标是了解设置播放信息如何从 ObjC 工作,以便稍后在 Rust 上实现它(使用生成的 ObjC 运行时绑定)。

所以现在我正在尝试在 ObjC 上编写一小段代码来设置播放信息(实际上没有播放任何内容)。 我找到了 https://github.com/MarshallOfSound/electron-media-service/blob/master/src/darwin/service.mm 并将其用作基础。

这是我现在拥有的代码:

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <objc/runtime.h>
#include "MediaPlayer/MPNowPlayingInfoCenter.h"
#include "MediaPlayer/MPRemoteCommandCenter.h"
#include "MediaPlayer/MPRemoteCommand.h"
#include "MediaPlayer/MPMediaItem.h"
#include "MediaPlayer/MPRemoteCommandEvent.h"


@interface NativeMediaController : NSObject { }
@end

@implementation NativeMediaController
- (MPRemoteCommandHandlerStatus)remotePlay {
    NSLog(@"Play");
    return MPRemoteCommandHandlerStatusSuccess;
  }
- (MPRemoteCommandHandlerStatus)remotePause {
    NSLog(@"Pause");
    return MPRemoteCommandHandlerStatusSuccess;
  }
- (MPRemoteCommandHandlerStatus)remoteTogglePlayPause {
    NSLog(@"PlayPause");
    return MPRemoteCommandHandlerStatusSuccess;
  }
- (MPRemoteCommandHandlerStatus)remoteNext {
    NSLog(@"Next");
    return MPRemoteCommandHandlerStatusSuccess;
  }
- (MPRemoteCommandHandlerStatus)remotePrev {
    NSLog(@"Previous");
    return MPRemoteCommandHandlerStatusSuccess;
  }

- (MPRemoteCommandHandlerStatus)remoteChangePlaybackPosition:(MPChangePlaybackPositionCommandEvent*)event {
    NSLog(@"ChangePlaybackPosition");
  return MPRemoteCommandHandlerStatusSuccess;
}

- (MPRemoteCommandHandlerStatus)move:(MPChangePlaybackPositionCommandEvent*)event {
    NSLog(@"Move");
  return MPRemoteCommandHandlerStatusSuccess;
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        NativeMediaController* controller = [[NativeMediaController alloc] init];

        MPRemoteCommandCenter *remoteCommandCenter = [MPRemoteCommandCenter sharedCommandCenter];
        [remoteCommandCenter playCommand].enabled = true;
        [remoteCommandCenter pauseCommand].enabled = true;
        [remoteCommandCenter togglePlayPauseCommand].enabled = true;
        [remoteCommandCenter changePlaybackPositionCommand].enabled = true;
        [remoteCommandCenter nextTrackCommand].enabled = true;
        [remoteCommandCenter previousTrackCommand].enabled = true;

        [[remoteCommandCenter playCommand] addTarget:controller action:@selector(remotePlay)];
        [[remoteCommandCenter pauseCommand] addTarget:controller action:@selector(remotePause)];
        [[remoteCommandCenter togglePlayPauseCommand] addTarget:controller action:@selector(remoteTogglePlayPause)];
        [[remoteCommandCenter changePlaybackPositionCommand] addTarget:controller action:@selector(remoteChangePlaybackPosition:)];
        [[remoteCommandCenter nextTrackCommand] addTarget:controller action:@selector(remoteNext)];
        [[remoteCommandCenter previousTrackCommand] addTarget:controller action:@selector(remotePrev)];
        
        NSMutableDictionary *songInfo = [[NSMutableDictionary alloc] init];
        [songInfo setObject:[NSString stringWithUTF8String:"Test title"] forKey:MPMediaItemPropertyTitle];
        [songInfo setObject:[NSString stringWithUTF8String:"Test artist"] forKey:MPMediaItemPropertyArtist];
        [songInfo setObject:[NSString stringWithUTF8String:"Test albumtitle"] forKey:MPMediaItemPropertyAlbumTitle];
        [songInfo setObject:[NSNumber numberWithFloat:60.0] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
        [songInfo setObject:[NSNumber numberWithFloat:360.0] forKey:MPMediaItemPropertyPlaybackDuration];
        [songInfo setObject:[NSNumber numberWithFloat:112233] forKey:MPMediaItemPropertyPersistentID];
        
        [MPNowPlayingInfoCenter defaultCenter].playbackState = MPNowPlayingPlaybackStatePlaying;
        [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];
        NSLog(@"End!");
        
        char input[50] = {0};
        printf("Enter anything to quit: ");
        scanf("%s", input);
    }
    return 0;
}

当执行这段代码时,我发现在 MacOs 播放信息小部件中没有效果。 不幸的是现在我不知道如何调试这个或者我在哪里可以找到更好的 ObjC 示例。

最后,我找到了导致我在玩 Apple Swift 示例时出现问题的原因。 有两个显示播放小部件的要求(我没有在任何地方找到它们的记录)已丢失:

  • 您应该为至少一项操作(播放、暂停)注册回调
  • 您应该将应用程序构建为应用程序,而不是控制台。如果您的程序未在 Dock 中显示为 运行 应用程序 - 播放小部件将无法工作。