mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Merge pull request #497 from Palakis/category-mediacontrol
Requests/Events: Media Source/VLC
This commit is contained in:
commit
eea56b4c71
@ -35,6 +35,7 @@ set(obs-websocket_SOURCES
|
||||
src/WSRequestHandler_StudioMode.cpp
|
||||
src/WSRequestHandler_Transitions.cpp
|
||||
src/WSRequestHandler_Outputs.cpp
|
||||
src/WSRequestHandler_MediaControl.cpp
|
||||
src/WSEvents.cpp
|
||||
src/Config.cpp
|
||||
src/Utils.cpp
|
||||
|
196
src/WSEvents.cpp
196
src/WSEvents.cpp
@ -277,6 +277,15 @@ void WSEvents::connectSourceSignals(obs_source_t* source) {
|
||||
signal_handler_connect(sh, "filter_add", OnSourceFilterAdded, this);
|
||||
signal_handler_connect(sh, "filter_remove", OnSourceFilterRemoved, this);
|
||||
signal_handler_connect(sh, "reorder_filters", OnSourceFilterOrderChanged, this);
|
||||
|
||||
signal_handler_connect(sh, "media_play", OnMediaPlaying, this);
|
||||
signal_handler_connect(sh, "media_pause", OnMediaPaused, this);
|
||||
signal_handler_connect(sh, "media_restart", OnMediaRestarted, this);
|
||||
signal_handler_connect(sh, "media_stopped", OnMediaStopped, this);
|
||||
signal_handler_connect(sh, "media_next", OnMediaNext, this);
|
||||
signal_handler_connect(sh, "media_previous", OnMediaPrevious, this);
|
||||
signal_handler_connect(sh, "media_started", OnMediaStarted, this);
|
||||
signal_handler_connect(sh, "media_ended", OnMediaEnded, this);
|
||||
|
||||
if (sourceType == OBS_SOURCE_TYPE_SCENE) {
|
||||
signal_handler_connect(sh, "reorder", OnSceneReordered, this);
|
||||
@ -326,6 +335,15 @@ void WSEvents::disconnectSourceSignals(obs_source_t* source) {
|
||||
signal_handler_disconnect(sh, "transition_start", OnTransitionBegin, this);
|
||||
signal_handler_disconnect(sh, "transition_stop", OnTransitionEnd, this);
|
||||
signal_handler_disconnect(sh, "transition_video_stop", OnTransitionVideoEnd, this);
|
||||
|
||||
signal_handler_disconnect(sh, "media_play", OnMediaPlaying, this);
|
||||
signal_handler_disconnect(sh, "media_pause", OnMediaPaused, this);
|
||||
signal_handler_disconnect(sh, "media_restart", OnMediaRestarted, this);
|
||||
signal_handler_disconnect(sh, "media_stopped", OnMediaStopped, this);
|
||||
signal_handler_disconnect(sh, "media_next", OnMediaNext, this);
|
||||
signal_handler_disconnect(sh, "media_previous", OnMediaPrevious, this);
|
||||
signal_handler_disconnect(sh, "media_started", OnMediaStarted, this);
|
||||
signal_handler_disconnect(sh, "media_ended", OnMediaEnded, this);
|
||||
}
|
||||
|
||||
void WSEvents::connectFilterSignals(obs_source_t* filter) {
|
||||
@ -411,6 +429,16 @@ QString WSEvents::getRecordingTimecode() {
|
||||
return Utils::nsToTimestamp(getRecordingTime());
|
||||
}
|
||||
|
||||
OBSDataAutoRelease getMediaSourceData(calldata_t* data) {
|
||||
OBSDataAutoRelease fields = obs_data_create();
|
||||
OBSSource source = calldata_get_pointer<obs_source_t>(data, "source");
|
||||
|
||||
obs_data_set_string(fields, "sourceName", obs_source_get_name(source));
|
||||
obs_data_set_string(fields, "sourceTypeId", obs_source_get_id(source));
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates a scene change.
|
||||
*
|
||||
@ -1388,6 +1416,174 @@ void WSEvents::OnSourceFilterOrderChanged(void* param, calldata_t* data) {
|
||||
self->broadcastUpdate("SourceFiltersReordered", fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* A media source has started playing.
|
||||
*
|
||||
* Note: This event is only emitted when something actively controls the media/VLC source. In other words, the source will never emit this on its own naturally.
|
||||
*
|
||||
* @return {String} `sourceName` Source name
|
||||
* @return {String} `sourceTypeId` The ID type of the source (Eg. `vlc_source` or `ffmpeg_source`)
|
||||
*
|
||||
* @api events
|
||||
* @name MediaPlaying
|
||||
* @category media
|
||||
* @since 4.9.0
|
||||
*/
|
||||
void WSEvents::OnMediaPlaying(void* param, calldata_t* data) {
|
||||
auto self = reinterpret_cast<WSEvents*>(param);
|
||||
|
||||
OBSDataAutoRelease fields = getMediaSourceData(data);
|
||||
|
||||
self->broadcastUpdate("MediaPlaying", fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* A media source has been paused.
|
||||
*
|
||||
* Note: This event is only emitted when something actively controls the media/VLC source. In other words, the source will never emit this on its own naturally.
|
||||
*
|
||||
* @return {String} `sourceName` Source name
|
||||
* @return {String} `sourceTypeId` The ID type of the source (Eg. `vlc_source` or `ffmpeg_source`)
|
||||
*
|
||||
* @api events
|
||||
* @name MediaPaused
|
||||
* @category media
|
||||
* @since 4.9.0
|
||||
*/
|
||||
void WSEvents::OnMediaPaused(void* param, calldata_t* data) {
|
||||
auto self = reinterpret_cast<WSEvents*>(param);
|
||||
|
||||
OBSDataAutoRelease fields = getMediaSourceData(data);
|
||||
|
||||
self->broadcastUpdate("MediaPaused", fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* A media source has been restarted.
|
||||
*
|
||||
* Note: This event is only emitted when something actively controls the media/VLC source. In other words, the source will never emit this on its own naturally.
|
||||
*
|
||||
* @return {String} `sourceName` Source name
|
||||
* @return {String} `sourceTypeId` The ID type of the source (Eg. `vlc_source` or `ffmpeg_source`)
|
||||
*
|
||||
* @api events
|
||||
* @name MediaRestarted
|
||||
* @category media
|
||||
* @since 4.9.0
|
||||
*/
|
||||
void WSEvents::OnMediaRestarted(void* param, calldata_t* data) {
|
||||
auto self = reinterpret_cast<WSEvents*>(param);
|
||||
|
||||
OBSDataAutoRelease fields = getMediaSourceData(data);
|
||||
|
||||
self->broadcastUpdate("MediaRestarted", fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* A media source has been stopped.
|
||||
*
|
||||
* Note: This event is only emitted when something actively controls the media/VLC source. In other words, the source will never emit this on its own naturally.
|
||||
*
|
||||
* @return {String} `sourceName` Source name
|
||||
* @return {String} `sourceTypeId` The ID type of the source (Eg. `vlc_source` or `ffmpeg_source`)
|
||||
*
|
||||
* @api events
|
||||
* @name MediaStopped
|
||||
* @category media
|
||||
* @since 4.9.0
|
||||
*/
|
||||
void WSEvents::OnMediaStopped(void* param, calldata_t* data) {
|
||||
auto self = reinterpret_cast<WSEvents*>(param);
|
||||
|
||||
OBSDataAutoRelease fields = getMediaSourceData(data);
|
||||
|
||||
self->broadcastUpdate("MediaStopped", fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* A media source has gone to the next item in the playlist.
|
||||
*
|
||||
* Note: This event is only emitted when something actively controls the media/VLC source. In other words, the source will never emit this on its own naturally.
|
||||
*
|
||||
* @return {String} `sourceName` Source name
|
||||
* @return {String} `sourceTypeId` The ID type of the source (Eg. `vlc_source` or `ffmpeg_source`)
|
||||
*
|
||||
* @api events
|
||||
* @name MediaNext
|
||||
* @category media
|
||||
* @since 4.9.0
|
||||
*/
|
||||
void WSEvents::OnMediaNext(void* param, calldata_t* data) {
|
||||
auto self = reinterpret_cast<WSEvents*>(param);
|
||||
|
||||
OBSDataAutoRelease fields = getMediaSourceData(data);
|
||||
|
||||
self->broadcastUpdate("MediaNext", fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* A media source has gone to the previous item in the playlist.
|
||||
*
|
||||
* Note: This event is only emitted when something actively controls the media/VLC source. In other words, the source will never emit this on its own naturally.
|
||||
*
|
||||
* @return {String} `sourceName` Source name
|
||||
* @return {String} `sourceTypeId` The ID type of the source (Eg. `vlc_source` or `ffmpeg_source`)
|
||||
*
|
||||
* @api events
|
||||
* @name MediaPrevious
|
||||
* @category media
|
||||
* @since 4.9.0
|
||||
*/
|
||||
void WSEvents::OnMediaPrevious(void* param, calldata_t* data) {
|
||||
auto self = reinterpret_cast<WSEvents*>(param);
|
||||
|
||||
OBSDataAutoRelease fields = getMediaSourceData(data);
|
||||
|
||||
self->broadcastUpdate("MediaPrevious", fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* A media source has been started.
|
||||
*
|
||||
* Note: These events are emitted by the OBS sources themselves. For example when the media file starts playing. The behavior depends on the type of media source being used.
|
||||
*
|
||||
* @return {String} `sourceName` Source name
|
||||
* @return {String} `sourceTypeId` The ID type of the source (Eg. `vlc_source` or `ffmpeg_source`)
|
||||
*
|
||||
* @api events
|
||||
* @name MediaStarted
|
||||
* @category media
|
||||
* @since 4.9.0
|
||||
*/
|
||||
void WSEvents::OnMediaStarted(void* param, calldata_t* data) {
|
||||
auto self = reinterpret_cast<WSEvents*>(param);
|
||||
|
||||
OBSDataAutoRelease fields = getMediaSourceData(data);
|
||||
|
||||
self->broadcastUpdate("MediaStarted", fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* A media source has ended.
|
||||
*
|
||||
* Note: These events are emitted by the OBS sources themselves. For example when the media file ends. The behavior depends on the type of media source being used.
|
||||
*
|
||||
* @return {String} `sourceName` Source name
|
||||
* @return {String} `sourceTypeId` The ID type of the source (Eg. `vlc_source` or `ffmpeg_source`)
|
||||
*
|
||||
* @api events
|
||||
* @name MediaEnded
|
||||
* @category media
|
||||
* @since 4.9.0
|
||||
*/
|
||||
void WSEvents::OnMediaEnded(void* param, calldata_t* data) {
|
||||
auto self = reinterpret_cast<WSEvents*>(param);
|
||||
|
||||
OBSDataAutoRelease fields = getMediaSourceData(data);
|
||||
|
||||
self->broadcastUpdate("MediaEnded", fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scene items have been reordered.
|
||||
*
|
||||
|
@ -135,6 +135,15 @@ private:
|
||||
static void OnSourceFilterRemoved(void* param, calldata_t* data);
|
||||
static void OnSourceFilterVisibilityChanged(void* param, calldata_t* data);
|
||||
static void OnSourceFilterOrderChanged(void* param, calldata_t* data);
|
||||
|
||||
static void OnMediaPlaying(void* param, calldata_t* data);
|
||||
static void OnMediaPaused(void* param, calldata_t* data);
|
||||
static void OnMediaRestarted(void* param, calldata_t* data);
|
||||
static void OnMediaStopped(void* param, calldata_t* data);
|
||||
static void OnMediaNext(void* param, calldata_t* data);
|
||||
static void OnMediaPrevious(void* param, calldata_t* data);
|
||||
static void OnMediaStarted(void* param, calldata_t* data);
|
||||
static void OnMediaEnded(void* param, calldata_t* data);
|
||||
|
||||
static void OnSceneReordered(void* param, calldata_t* data);
|
||||
static void OnSceneItemAdd(void* param, calldata_t* data);
|
||||
|
@ -154,7 +154,19 @@ const QHash<QString, RpcMethodHandler> WSRequestHandler::messageMap {
|
||||
{ "ListOutputs", &WSRequestHandler::ListOutputs },
|
||||
{ "GetOutputInfo", &WSRequestHandler::GetOutputInfo },
|
||||
{ "StartOutput", &WSRequestHandler::StartOutput },
|
||||
{ "StopOutput", &WSRequestHandler::StopOutput }
|
||||
{ "StopOutput", &WSRequestHandler::StopOutput },
|
||||
|
||||
{ "PlayPauseMedia", &WSRequestHandler::PlayPauseMedia },
|
||||
{ "RestartMedia", &WSRequestHandler::RestartMedia },
|
||||
{ "StopMedia", &WSRequestHandler::StopMedia },
|
||||
{ "NextMedia", &WSRequestHandler::NextMedia },
|
||||
{ "PreviousMedia", &WSRequestHandler::PreviousMedia },
|
||||
{ "GetMediaDuration", &WSRequestHandler::GetMediaDuration },
|
||||
{ "GetMediaTime", &WSRequestHandler::GetMediaTime },
|
||||
{ "SetMediaTime", &WSRequestHandler::SetMediaTime },
|
||||
{ "ScrubMedia", &WSRequestHandler::ScrubMedia },
|
||||
{ "GetMediaState", &WSRequestHandler::GetMediaState },
|
||||
{ "GetMediaSourcesList", &WSRequestHandler::GetMediaSourcesList }
|
||||
};
|
||||
|
||||
const QSet<QString> WSRequestHandler::authNotRequired {
|
||||
|
@ -172,4 +172,16 @@ class WSRequestHandler {
|
||||
RpcResponse GetOutputInfo(const RpcRequest&);
|
||||
RpcResponse StartOutput(const RpcRequest&);
|
||||
RpcResponse StopOutput(const RpcRequest&);
|
||||
|
||||
RpcResponse PlayPauseMedia(const RpcRequest&);
|
||||
RpcResponse RestartMedia(const RpcRequest&);
|
||||
RpcResponse StopMedia(const RpcRequest&);
|
||||
RpcResponse NextMedia(const RpcRequest&);
|
||||
RpcResponse PreviousMedia(const RpcRequest&);
|
||||
RpcResponse GetMediaDuration(const RpcRequest&);
|
||||
RpcResponse GetMediaTime(const RpcRequest&);
|
||||
RpcResponse SetMediaTime(const RpcRequest&);
|
||||
RpcResponse ScrubMedia(const RpcRequest&);
|
||||
RpcResponse GetMediaState(const RpcRequest&);
|
||||
RpcResponse GetMediaSourcesList(const RpcRequest&);
|
||||
};
|
||||
|
396
src/WSRequestHandler_MediaControl.cpp
Normal file
396
src/WSRequestHandler_MediaControl.cpp
Normal file
@ -0,0 +1,396 @@
|
||||
#include "Utils.h"
|
||||
|
||||
#include "WSRequestHandler.h"
|
||||
|
||||
bool isMediaSource(const QString& sourceKind)
|
||||
{
|
||||
return (sourceKind == "vlc_source" || sourceKind == "ffmpeg_source");
|
||||
}
|
||||
|
||||
QString getSourceMediaState(obs_source_t *source)
|
||||
{
|
||||
QString mediaState;
|
||||
enum obs_media_state mstate = obs_source_media_get_state(source);
|
||||
switch (mstate) {
|
||||
case OBS_MEDIA_STATE_NONE:
|
||||
mediaState = "none";
|
||||
break;
|
||||
case OBS_MEDIA_STATE_PLAYING:
|
||||
mediaState = "playing";
|
||||
break;
|
||||
case OBS_MEDIA_STATE_OPENING:
|
||||
mediaState = "opening";
|
||||
break;
|
||||
case OBS_MEDIA_STATE_BUFFERING:
|
||||
mediaState = "buffering";
|
||||
break;
|
||||
case OBS_MEDIA_STATE_PAUSED:
|
||||
mediaState = "paused";
|
||||
break;
|
||||
case OBS_MEDIA_STATE_STOPPED:
|
||||
mediaState = "stopped";
|
||||
break;
|
||||
case OBS_MEDIA_STATE_ENDED:
|
||||
mediaState = "ended";
|
||||
break;
|
||||
case OBS_MEDIA_STATE_ERROR:
|
||||
mediaState = "error";
|
||||
break;
|
||||
default:
|
||||
mediaState = "unknown";
|
||||
}
|
||||
return mediaState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause or play a media source. Supports ffmpeg and vlc media sources (as of OBS v25.0.8)
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
* @param {boolean} `playPause` Whether to pause or play the source. `false` for play, `true` for pause.
|
||||
*
|
||||
* @api requests
|
||||
* @name PlayPauseMedia
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::PlayPauseMedia(const RpcRequest& request) {
|
||||
if ((!request.hasField("sourceName")) || (!request.hasField("playPause"))) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
bool playPause = obs_data_get_bool(request.parameters(), "playPause");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
obs_source_media_play_pause(source, playPause);
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart a media source. Supports ffmpeg and vlc media sources (as of OBS v25.0.8)
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
*
|
||||
* @api requests
|
||||
* @name RestartMedia
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::RestartMedia(const RpcRequest& request) {
|
||||
if (!request.hasField("sourceName")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
obs_source_media_restart(source);
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop a media source. Supports ffmpeg and vlc media sources (as of OBS v25.0.8)
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
*
|
||||
* @api requests
|
||||
* @name StopMedia
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::StopMedia(const RpcRequest& request) {
|
||||
if (!request.hasField("sourceName")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
obs_source_media_stop(source);
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip to the next media item in the playlist. Supports only vlc media source (as of OBS v25.0.8)
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
*
|
||||
* @api requests
|
||||
* @name NextMedia
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::NextMedia(const RpcRequest& request) {
|
||||
if (!request.hasField("sourceName")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
obs_source_media_next(source);
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to the previous media item in the playlist. Supports only vlc media source (as of OBS v25.0.8)
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
*
|
||||
* @api requests
|
||||
* @name PreviousMedia
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::PreviousMedia(const RpcRequest& request) {
|
||||
if (!request.hasField("sourceName")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
obs_source_media_previous(source);
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of media in milliseconds. Supports ffmpeg and vlc media sources (as of OBS v25.0.8)
|
||||
* Note: For some reason, for the first 5 or so seconds that the media is playing, the total duration can be off by upwards of 50ms.
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
*
|
||||
* @return {int} `mediaDuration` The total length of media in milliseconds..
|
||||
*
|
||||
* @api requests
|
||||
* @name GetMediaDuration
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::GetMediaDuration(const RpcRequest& request) {
|
||||
if (!request.hasField("sourceName")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_int(response, "mediaDuration", obs_source_media_get_duration(source));
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current timestamp of media in milliseconds. Supports ffmpeg and vlc media sources (as of OBS v25.0.8)
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
*
|
||||
* @return {int} `timestamp` The time in milliseconds since the start of the media.
|
||||
*
|
||||
* @api requests
|
||||
* @name GetMediaTime
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::GetMediaTime(const RpcRequest& request) {
|
||||
if (!request.hasField("sourceName")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_int(response, "timestamp", obs_source_media_get_time(source));
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timestamp of a media source. Supports ffmpeg and vlc media sources (as of OBS v25.0.8)
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
* @param {int} `timestamp` Milliseconds to set the timestamp to.
|
||||
*
|
||||
* @api requests
|
||||
* @name SetMediaTime
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::SetMediaTime(const RpcRequest& request) {
|
||||
if (!request.hasField("sourceName") || !request.hasField("timestamp")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
int64_t timestamp = (int64_t)obs_data_get_int(request.parameters(), "timestamp");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
obs_source_media_set_time(source, timestamp);
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrub media using a supplied offset. Supports ffmpeg and vlc media sources (as of OBS v25.0.8)
|
||||
* Note: Due to processing/network delays, this request is not perfect. The processing rate of this request has also not been tested.
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
* @param {int} `timeOffset` Millisecond offset (positive or negative) to offset the current media position.
|
||||
*
|
||||
* @api requests
|
||||
* @name ScrubMedia
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::ScrubMedia(const RpcRequest& request) {
|
||||
if (!request.hasField("sourceName") || !request.hasField("timeOffset")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
int64_t timeOffset = (int64_t)obs_data_get_int(request.parameters(), "timeOffset");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
int64_t newTime = obs_source_media_get_time(source) + timeOffset;
|
||||
if (newTime < 0) {
|
||||
newTime = 0;
|
||||
}
|
||||
|
||||
obs_source_media_set_time(source, newTime);
|
||||
return request.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current playing state of a media source. Supports ffmpeg and vlc media sources (as of OBS v25.0.8)
|
||||
*
|
||||
* @param {String} `sourceName` Source name.
|
||||
*
|
||||
* @return {String} `mediaState` The media state of the provided source. States: `none`, `playing`, `opening`, `buffering`, `paused`, `stopped`, `ended`, `error`, `unknown`
|
||||
*
|
||||
* @api requests
|
||||
* @name GetMediaState
|
||||
* @category media control
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::GetMediaState(const RpcRequest& request) {
|
||||
if (!request.hasField("sourceName")) {
|
||||
return request.failed("missing request parameters");
|
||||
}
|
||||
|
||||
QString sourceName = obs_data_get_string(request.parameters(), "sourceName");
|
||||
if (sourceName.isEmpty()) {
|
||||
return request.failed("invalid request parameters");
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName.toUtf8());
|
||||
if (!source) {
|
||||
return request.failed("specified source doesn't exist");
|
||||
}
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_string(response, "mediaState", getSourceMediaState(source).toUtf8());
|
||||
|
||||
return request.success(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the media state of all media sources (vlc and media source)
|
||||
*
|
||||
* @return {Array<Object>} `mediaSources` Array of sources
|
||||
* @return {String} `mediaSources.*.sourceName` Unique source name
|
||||
* @return {String} `mediaSources.*.sourceKind` Unique source internal type (a.k.a `ffmpeg_source` or `vlc_source`)
|
||||
* @return {String} `mediaSources.*.mediaState` The current state of media for that source. States: `none`, `playing`, `opening`, `buffering`, `paused`, `stopped`, `ended`, `error`, `unknown`
|
||||
*
|
||||
* @api requests
|
||||
* @name GetMediaSourcesList
|
||||
* @category sources
|
||||
* @since 4.9.0
|
||||
*/
|
||||
RpcResponse WSRequestHandler::GetMediaSourcesList(const RpcRequest& request)
|
||||
{
|
||||
OBSDataArrayAutoRelease sourcesArray = obs_data_array_create();
|
||||
|
||||
auto sourceEnumProc = [](void* privateData, obs_source_t* source) -> bool {
|
||||
obs_data_array_t* sourcesArray = (obs_data_array_t*)privateData;
|
||||
|
||||
QString sourceTypeId = obs_source_get_id(source);
|
||||
if (isMediaSource(sourceTypeId)) {
|
||||
OBSDataAutoRelease sourceData = obs_data_create();
|
||||
obs_data_set_string(sourceData, "sourceName", obs_source_get_name(source));
|
||||
obs_data_set_string(sourceData, "sourceKind", sourceTypeId.toUtf8());
|
||||
|
||||
QString mediaState = getSourceMediaState(source);
|
||||
obs_data_set_string(sourceData, "mediaState", mediaState.toUtf8());
|
||||
|
||||
obs_data_array_push_back(sourcesArray, sourceData);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
obs_enum_sources(sourceEnumProc, sourcesArray);
|
||||
|
||||
OBSDataAutoRelease response = obs_data_create();
|
||||
obs_data_set_array(response, "mediaSources", sourcesArray);
|
||||
return request.success(response);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user