Add an ability to get player state and execute commands
This commit is contained in:
parent
48cfa93e5c
commit
d149f8625f
@ -1,6 +1,7 @@
|
||||
module aimpremote;
|
||||
|
||||
import core.sys.windows.windows;
|
||||
import std.typecons : Nullable;
|
||||
|
||||
private const wstring AIMPRemoteAccessClass = "AIMP2_RemoteInfo";
|
||||
private const int AIMPRemoteAccessMapFileSize = 2048;
|
||||
@ -26,6 +27,21 @@ private struct AIMPRemoteFileInfo
|
||||
DWORD[6] deprecated2;
|
||||
};
|
||||
|
||||
private const int WM_AIMP_COMMAND = WM_USER + 0x75;
|
||||
private const int WM_AIMP_NOTIFY = WM_USER + 0x76;
|
||||
private const int WM_AIMP_PROPERTY = WM_USER + 0x77;
|
||||
|
||||
private const int AIMP_RA_PROPVALUE_GET = 0;
|
||||
private const int AIMP_RA_PROPVALUE_SET = 1;
|
||||
private const int AIMP_RA_PROPERTY_MASK = 0xFFFFFFF0;
|
||||
|
||||
private const int AIMP_RA_PROPERTY_PLAYER_STATE = 0x40;
|
||||
private const int AIMP_RA_PROPERTY_VOLUME = 0x50;
|
||||
|
||||
private const int AIMP_RA_CMD_BASE = 10;
|
||||
private const int AIMP_RA_CMD_NEXT = AIMP_RA_CMD_BASE + 7;
|
||||
private const int AIMP_RA_CMD_PREV = AIMP_RA_CMD_BASE + 8;
|
||||
|
||||
private enum TagItem {
|
||||
Album, Artist, Date, FileName, Genre, Title
|
||||
}
|
||||
@ -36,12 +52,55 @@ public struct TrackInfo {
|
||||
wstring genre;
|
||||
};
|
||||
|
||||
public static TrackInfo getInfo() {
|
||||
public enum PlayerState {
|
||||
Off, Stopped, Paused, Playing
|
||||
}
|
||||
|
||||
public static PlayerState getPlayerState() {
|
||||
auto hwnd = findPlayerWindow();
|
||||
if (hwnd == null) {
|
||||
return PlayerState.Off;
|
||||
}
|
||||
|
||||
const auto state = SendMessage(hwnd, WM_AIMP_PROPERTY,
|
||||
AIMP_RA_PROPERTY_PLAYER_STATE | AIMP_RA_PROPVALUE_GET, 0);
|
||||
switch (state) {
|
||||
default: return PlayerState.Stopped;
|
||||
case 1: return PlayerState.Paused;
|
||||
case 2: return PlayerState.Playing;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setVolume(ubyte volume) {
|
||||
auto hwnd = findPlayerWindow();
|
||||
if (hwnd != null) {
|
||||
SendMessage(hwnd, WM_AIMP_PROPERTY,
|
||||
AIMP_RA_PROPERTY_VOLUME | AIMP_RA_PROPVALUE_SET, volume);
|
||||
}
|
||||
}
|
||||
|
||||
public static void nextTrack() {
|
||||
auto hwnd = findPlayerWindow();
|
||||
if (hwnd != null) {
|
||||
SendMessage(hwnd, WM_AIMP_COMMAND, AIMP_RA_CMD_NEXT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static Nullable!TrackInfo getInfo() {
|
||||
import std.conv : to;
|
||||
import std.traits : EnumMembers;
|
||||
Nullable!TrackInfo result = Nullable!TrackInfo.init;
|
||||
|
||||
auto haimp = OpenFileMapping(FILE_MAP_READ, 0, AIMPRemoteAccessClass.ptr);
|
||||
if (haimp == null) {
|
||||
result.nullify();
|
||||
return result;
|
||||
}
|
||||
const auto hfilemap = MapViewOfFile(haimp, FILE_MAP_READ, 0, 0, AIMPRemoteAccessMapFileSize);
|
||||
if (hfilemap == null) {
|
||||
result.nullify();
|
||||
return result;
|
||||
}
|
||||
|
||||
AIMPRemoteFileInfo* info = cast(AIMPRemoteFileInfo*) hfilemap;
|
||||
auto bytes = (cast(ubyte*) hfilemap)[0 .. AIMPRemoteAccessMapFileSize];
|
||||
@ -65,11 +124,12 @@ public static TrackInfo getInfo() {
|
||||
pbuff += length * wcharsize;
|
||||
}
|
||||
|
||||
TrackInfo result = {
|
||||
TrackInfo r = {
|
||||
artist: trackInfo[TagItem.Artist],
|
||||
title: trackInfo[TagItem.Title],
|
||||
genre: trackInfo[TagItem.Genre]
|
||||
};
|
||||
result = Nullable!TrackInfo(r);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -86,7 +146,7 @@ private static HWND findPlayerWindow() {
|
||||
AIMPRemoteFileInfo* info = cast(AIMPRemoteFileInfo*) hfilemap;
|
||||
write("Bitrate: ");
|
||||
writeln(info.bitRate);
|
||||
write("Samplerate: ");
|
||||
write("Samlerate: ");
|
||||
writeln(info.sampleRate);
|
||||
write("fileSize: ");
|
||||
writeln(info.fileSize);
|
||||
|
@ -10,6 +10,10 @@ void main()
|
||||
http.handle.set(CurlOption.ssl_verifypeer, 0);
|
||||
|
||||
auto track = getInfo();
|
||||
if (track.isNull) {
|
||||
writeln("No data");
|
||||
return;
|
||||
}
|
||||
|
||||
auto content = post("https://annimon.com/json/nowplay", [
|
||||
"login" : "test",
|
||||
|
Loading…
Reference in New Issue
Block a user