MediaPlayer: Add per-track scripting items
Somewhat restructures scripting interface: Playlist items can be accessed/added/removed through PlaylistTrack, current item can be accessed through CurrentTrack. Also adds an IsPlaying property. Fixes #13881 Change-Id: Iad333ec20ab00ff57147c7e1359a24dea04d6aa2 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5316 Reviewed-by: Jérôme Duval <jerome.duval@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
cc9bc8c6fb
commit
87db9cb2a6
@ -115,56 +115,45 @@ enum {
|
|||||||
static property_info sPropertyInfo[] = {
|
static property_info sPropertyInfo[] = {
|
||||||
{ "Next", { B_EXECUTE_PROPERTY },
|
{ "Next", { B_EXECUTE_PROPERTY },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Skip to the next track.", 0
|
"Skips to the next track.", 0
|
||||||
},
|
},
|
||||||
{ "Prev", { B_EXECUTE_PROPERTY },
|
{ "Prev", { B_EXECUTE_PROPERTY },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Skip to the previous track.", 0
|
"Skips to the previous track.", 0
|
||||||
},
|
},
|
||||||
{ "Play", { B_EXECUTE_PROPERTY },
|
{ "Play", { B_EXECUTE_PROPERTY },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Start playing.", 0
|
"Starts playing.", 0
|
||||||
},
|
},
|
||||||
{ "Stop", { B_EXECUTE_PROPERTY },
|
{ "Stop", { B_EXECUTE_PROPERTY },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Stop playing.", 0
|
"Stops playing.", 0
|
||||||
},
|
},
|
||||||
{ "Pause", { B_EXECUTE_PROPERTY },
|
{ "Pause", { B_EXECUTE_PROPERTY },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Pause playback.", 0
|
"Pauses playback.", 0
|
||||||
|
},
|
||||||
|
{ "IsPlaying", { B_GET_PROPERTY },
|
||||||
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
|
"Gets whether or not the player is unpaused.", 0,
|
||||||
|
{ B_BOOL_TYPE }
|
||||||
},
|
},
|
||||||
{ "TogglePlaying", { B_EXECUTE_PROPERTY },
|
{ "TogglePlaying", { B_EXECUTE_PROPERTY },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Toggle pause/play.", 0
|
"Toggles pause/play.", 0
|
||||||
},
|
},
|
||||||
{ "Mute", { B_EXECUTE_PROPERTY },
|
{ "Mute", { B_EXECUTE_PROPERTY },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Toggle mute.", 0
|
"Toggles mute.", 0
|
||||||
},
|
},
|
||||||
{ "Volume", { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
|
{ "Volume", { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Gets/sets the volume (0.0-2.0).", 0,
|
"Gets/sets the volume (0.0-2.0).", 0,
|
||||||
{ B_FLOAT_TYPE }
|
{ B_FLOAT_TYPE }
|
||||||
},
|
},
|
||||||
{ "URI", { B_GET_PROPERTY, 0 },
|
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
|
||||||
"Gets the URI of the currently playing item.", 0,
|
|
||||||
{ B_STRING_TYPE }
|
|
||||||
},
|
|
||||||
{ "TrackNumber", { B_GET_PROPERTY, 0 },
|
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
|
||||||
"Gets the number of the current track playing.", 0,
|
|
||||||
{ B_INT32_TYPE }
|
|
||||||
},
|
|
||||||
{ "ToggleFullscreen", { B_EXECUTE_PROPERTY },
|
{ "ToggleFullscreen", { B_EXECUTE_PROPERTY },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Toggle fullscreen.", 0
|
"Toggles fullscreen.", 0
|
||||||
},
|
|
||||||
{ "Duration", { B_GET_PROPERTY, 0 },
|
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
|
||||||
"Gets the duration of the currently playing item "
|
|
||||||
"in microseconds.", 0,
|
|
||||||
{ B_INT64_TYPE }
|
|
||||||
},
|
},
|
||||||
{ "Position", { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
|
{ "Position", { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
@ -173,19 +162,73 @@ static property_info sPropertyInfo[] = {
|
|||||||
},
|
},
|
||||||
{ "Seek", { B_SET_PROPERTY },
|
{ "Seek", { B_SET_PROPERTY },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Seek by the specified amounts of microseconds.", 0,
|
"Seeks by the specified amount in microseconds.", 0,
|
||||||
{ B_INT64_TYPE }
|
{ B_INT64_TYPE }
|
||||||
},
|
},
|
||||||
{ "PlaylistTrackCount", { B_GET_PROPERTY, 0 },
|
{ "PlaylistTrack", { B_COUNT_PROPERTIES, B_CREATE_PROPERTY, 0 },
|
||||||
{ B_DIRECT_SPECIFIER, 0 },
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
"Gets the number of tracks in Playlist.", 0,
|
"Counts items in the Playlist or appends an item by URI.", 0,
|
||||||
{ B_INT16_TYPE }
|
{ B_INT32_TYPE }
|
||||||
},
|
},
|
||||||
{ "PlaylistTrackTitle", { B_GET_PROPERTY, 0 },
|
{ "PlaylistTrack", { B_DELETE_PROPERTY, 0 },
|
||||||
{ B_INDEX_SPECIFIER, 0 },
|
{ B_INDEX_SPECIFIER, 0 },
|
||||||
"Gets the title of the nth track in Playlist.", 0,
|
"Deletes the nth item in Playlist.", 0,
|
||||||
{ B_STRING_TYPE }
|
{ B_STRING_TYPE }
|
||||||
},
|
},
|
||||||
|
{ "PlaylistTrack", {},
|
||||||
|
{ B_INDEX_SPECIFIER, 0 },
|
||||||
|
"... of PlaylistTrack { index } of ...", 0
|
||||||
|
},
|
||||||
|
{ "CurrentTrack", {},
|
||||||
|
{},
|
||||||
|
"... of CurrentTrack of ...", 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static property_info sItemPropertyInfo[] = {
|
||||||
|
{ "Title", { B_GET_PROPERTY, 0 },
|
||||||
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
|
"Gets the title of the item.", 0,
|
||||||
|
{ B_STRING_TYPE }
|
||||||
|
},
|
||||||
|
{ "URI", { B_GET_PROPERTY, 0 },
|
||||||
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
|
"Gets the URI of the item.", 0,
|
||||||
|
{ B_STRING_TYPE }
|
||||||
|
},
|
||||||
|
{ "Duration", { B_GET_PROPERTY, 0 },
|
||||||
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
|
"Gets the duration of the item in microseconds.", 0,
|
||||||
|
{ B_INT64_TYPE }
|
||||||
|
},
|
||||||
|
{ "Author", { B_GET_PROPERTY, 0 },
|
||||||
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
|
"Gets the author of the item.", 0,
|
||||||
|
{ B_STRING_TYPE }
|
||||||
|
},
|
||||||
|
{ "Album", { B_GET_PROPERTY, 0 },
|
||||||
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
|
"Gets the album of the item.", 0,
|
||||||
|
{ B_STRING_TYPE }
|
||||||
|
},
|
||||||
|
{ "TrackNumber", { B_GET_PROPERTY, 0 },
|
||||||
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
|
"Gets the track number of the item.", 0,
|
||||||
|
{ B_INT32_TYPE }
|
||||||
|
},
|
||||||
|
{ "PlaylistIndex", { B_GET_PROPERTY, 0 },
|
||||||
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
|
"Gets the item's position in Playlist.", 0,
|
||||||
|
{ B_INT32_TYPE }
|
||||||
|
},
|
||||||
|
{ "Suites", { B_GET_PROPERTY, 0 },
|
||||||
|
{ B_DIRECT_SPECIFIER, 0 },
|
||||||
|
NULL, 0,
|
||||||
|
{ B_PROPERTY_INFO_TYPE }
|
||||||
|
},
|
||||||
|
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
@ -491,6 +534,10 @@ MainWin::MessageReceived(BMessage* msg)
|
|||||||
case B_EXECUTE_PROPERTY:
|
case B_EXECUTE_PROPERTY:
|
||||||
case B_GET_PROPERTY:
|
case B_GET_PROPERTY:
|
||||||
case B_SET_PROPERTY:
|
case B_SET_PROPERTY:
|
||||||
|
case B_COUNT_PROPERTIES:
|
||||||
|
case B_CREATE_PROPERTY:
|
||||||
|
case B_DELETE_PROPERTY:
|
||||||
|
case B_GET_SUPPORTED_SUITES:
|
||||||
{
|
{
|
||||||
BMessage reply(B_REPLY);
|
BMessage reply(B_REPLY);
|
||||||
status_t result = B_BAD_SCRIPT_SYNTAX;
|
status_t result = B_BAD_SCRIPT_SYNTAX;
|
||||||
@ -499,14 +546,12 @@ MainWin::MessageReceived(BMessage* msg)
|
|||||||
int32 what;
|
int32 what;
|
||||||
const char* property;
|
const char* property;
|
||||||
|
|
||||||
if (msg->GetCurrentSpecifier(&index, &specifier, &what,
|
if (msg->GetCurrentSpecifier(&index, &specifier, &what, &property) != B_OK)
|
||||||
&property) != B_OK) {
|
|
||||||
return BWindow::MessageReceived(msg);
|
return BWindow::MessageReceived(msg);
|
||||||
}
|
|
||||||
|
|
||||||
BPropertyInfo propertyInfo(sPropertyInfo);
|
BPropertyInfo propertyInfo(sPropertyInfo);
|
||||||
switch (propertyInfo.FindMatch(msg, index, &specifier, what,
|
int32 match = propertyInfo.FindMatch(msg, index, &specifier, what, property);
|
||||||
property)) {
|
switch (match) {
|
||||||
case 0:
|
case 0:
|
||||||
fControls->SkipForward();
|
fControls->SkipForward();
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
@ -533,16 +578,20 @@ MainWin::MessageReceived(BMessage* msg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
|
result = reply.AddBool("result", fController->IsPlaying());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
fController->TogglePlaying();
|
fController->TogglePlaying();
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 7:
|
||||||
fController->ToggleMute();
|
fController->ToggleMute();
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 8:
|
||||||
{
|
{
|
||||||
if (msg->what == B_GET_PROPERTY) {
|
if (msg->what == B_GET_PROPERTY) {
|
||||||
result = reply.AddFloat("result",
|
result = reply.AddFloat("result",
|
||||||
@ -556,49 +605,11 @@ MainWin::MessageReceived(BMessage* msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 8:
|
|
||||||
{
|
|
||||||
if (msg->what == B_GET_PROPERTY) {
|
|
||||||
BAutolock _(fPlaylist);
|
|
||||||
const PlaylistItem* item = fController->Item();
|
|
||||||
if (item == NULL) {
|
|
||||||
result = B_NO_INIT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = reply.AddString("result", item->LocationURI());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
{
|
|
||||||
if (msg->what == B_GET_PROPERTY) {
|
|
||||||
BAutolock _(fPlaylist);
|
|
||||||
const PlaylistItem* item = fController->Item();
|
|
||||||
if (item == NULL) {
|
|
||||||
result = B_NO_INIT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = reply.AddInt32("result", item->TrackNumber());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 10:
|
|
||||||
PostMessage(M_TOGGLE_FULLSCREEN);
|
PostMessage(M_TOGGLE_FULLSCREEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 11:
|
case 10:
|
||||||
if (msg->what != B_GET_PROPERTY)
|
|
||||||
break;
|
|
||||||
|
|
||||||
result = reply.AddInt64("result",
|
|
||||||
fController->TimeDuration());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 12:
|
|
||||||
{
|
{
|
||||||
if (msg->what == B_GET_PROPERTY) {
|
if (msg->what == B_GET_PROPERTY) {
|
||||||
result = reply.AddInt64("result",
|
result = reply.AddInt64("result",
|
||||||
@ -613,7 +624,7 @@ MainWin::MessageReceived(BMessage* msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 13:
|
case 11:
|
||||||
{
|
{
|
||||||
if (msg->what != B_SET_PROPERTY)
|
if (msg->what != B_SET_PROPERTY)
|
||||||
break;
|
break;
|
||||||
@ -627,22 +638,150 @@ MainWin::MessageReceived(BMessage* msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 14:
|
case 12:
|
||||||
result = reply.AddInt16("result", fPlaylist->CountItems());
|
{
|
||||||
|
BAutolock _(fPlaylist);
|
||||||
|
if (msg->what == B_COUNT_PROPERTIES)
|
||||||
|
result = reply.AddInt32("result", fPlaylist->CountItems());
|
||||||
|
else if (msg->what == B_CREATE_PROPERTY) {
|
||||||
|
result = B_OK;
|
||||||
|
int32 i = msg->GetInt32("index", fPlaylist->CountItems());
|
||||||
|
if (i > fPlaylist->CountItems()) {
|
||||||
|
result = B_BAD_INDEX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BString urlString;
|
||||||
|
entry_ref fileRef;
|
||||||
|
for (int32 j = 0; msg->FindString("data", j, &urlString) == B_OK; j++) {
|
||||||
|
BUrl url(urlString);
|
||||||
|
if (url.IsValid() && url.Protocol() != "file") {
|
||||||
|
UrlPlaylistItem* item = new UrlPlaylistItem(url);
|
||||||
|
if (!fPlaylist->AddItem(item, i + j)) {
|
||||||
|
result = B_NO_INIT;
|
||||||
|
delete item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!urlString.IsEmpty()) {
|
||||||
|
BString path = url.Path().String();
|
||||||
|
if (path.IsEmpty())
|
||||||
|
path = urlString;
|
||||||
|
|
||||||
|
result = BEntry(path.String()).GetRef(&fileRef);
|
||||||
|
if (result == B_OK && msg->AddRef("refs", &fileRef) != B_OK)
|
||||||
|
result = B_NO_INIT;
|
||||||
|
if (result != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 15:
|
for (int32 j = 0; msg->FindRef("refs", j, &fileRef) == B_OK; j++)
|
||||||
{
|
if (!BEntry(&fileRef).Exists()) {
|
||||||
int32 i = specifier.GetInt32("index", 0);
|
result = B_ENTRY_NOT_FOUND;
|
||||||
if (i >= fPlaylist->CountItems()) {
|
break;
|
||||||
|
} else {
|
||||||
|
FilePlaylistItem* item = new FilePlaylistItem(fileRef);
|
||||||
|
if (!fPlaylist->AddItem(item, i + j)) {
|
||||||
result = B_NO_INIT;
|
result = B_NO_INIT;
|
||||||
|
delete item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 13:
|
||||||
|
{
|
||||||
|
int32 i = 0;
|
||||||
|
int32 count = fPlaylist->CountItems();
|
||||||
|
if (specifier.FindInt32("index", &i) != B_OK || i >= count) {
|
||||||
|
result = B_BAD_INDEX;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAutolock _(fPlaylist);
|
BAutolock _(fPlaylist);
|
||||||
const PlaylistItem* item = fPlaylist->ItemAt(i);
|
if (msg->what == B_DELETE_PROPERTY)
|
||||||
result = item == NULL ? B_NO_INIT
|
result = fPlaylist->RemoveItem(i) == NULL ? B_NO_INIT : B_OK;
|
||||||
: reply.AddString("result", item->Title());
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PlaylistItem and CurrentItem
|
||||||
|
case 14:
|
||||||
|
case 15:
|
||||||
|
{
|
||||||
|
BPropertyInfo itemPropertyInfo(sItemPropertyInfo);
|
||||||
|
if (msg->what == B_GET_SUPPORTED_SUITES) {
|
||||||
|
result = reply.AddFlat("messages", &itemPropertyInfo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAutolock _(fPlaylist);
|
||||||
|
int32 i = fPlaylist->CurrentItemIndex();
|
||||||
|
if (match == 14 && (specifier.FindInt32("index", &i) != B_OK
|
||||||
|
|| i >= fPlaylist->CountItems() || i < 0)) {
|
||||||
|
result = B_BAD_INDEX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->SetCurrentSpecifier(0);
|
||||||
|
if (msg->GetCurrentSpecifier(&index, &specifier, &what, &property) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const PlaylistItem* item = NULL;
|
||||||
|
if (match == 14)
|
||||||
|
item = fPlaylist->ItemAt(i);
|
||||||
|
else
|
||||||
|
item = fController->Item();
|
||||||
|
if (item == NULL) {
|
||||||
|
result = B_NO_INIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (itemPropertyInfo.FindMatch(msg, index, &specifier, what, property)) {
|
||||||
|
case 0:
|
||||||
|
result = reply.AddString("result", item->Title());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
result = reply.AddString("result", item->LocationURI());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
// Duration requires non-const item
|
||||||
|
if (match == 14) {
|
||||||
|
PlaylistItem* nitem = fPlaylist->ItemAt(i);
|
||||||
|
if (nitem == NULL)
|
||||||
|
result = B_NO_INIT;
|
||||||
|
else
|
||||||
|
result = reply.AddInt64("result", nitem->Duration());
|
||||||
|
} else
|
||||||
|
result = reply.AddInt64("result", fController->TimeDuration());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
result = reply.AddString("result", item->Author());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
result = reply.AddString("result", item->Album());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
result = reply.AddInt32("result", item->TrackNumber());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
result = reply.AddInt32("result", i);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
result = reply.AddFlat("messages", &itemPropertyInfo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user