struct AddSourceData {
obs_source_t *source;
bool visible;
obs_transform_info *transform = nullptr;
obs_sceneitem_crop *crop = nullptr;
obs_blending_method *blend_method = nullptr;
obs_blending_type *blend_mode = nullptr;
};
//添加源及设置滤镜
void AddSourceEx(void *_data, obs_scene_t *scene)
{
AddSourceData *data = (AddSourceData *)_data;
obs_sceneitem_t *sceneitem;
sceneitem = obs_scene_add(scene, data->source);
if (data->transform != nullptr)
obs_sceneitem_set_info(sceneitem, data->transform);
if (data->crop != nullptr)
obs_sceneitem_set_crop(sceneitem, data->crop);
if (data->blend_method != nullptr)
obs_sceneitem_set_blending_method(sceneitem, *data->blend_method);
if (data->blend_mode != nullptr)
obs_sceneitem_set_blending_mode(sceneitem, *data->blend_mode);
obs_sceneitem_set_visible(sceneitem, data->visible);
obs_sceneitem_set_locked(sceneitem, true);
obs_video_info ovi;
obs_get_video_info(&ovi);
obs_transform_info info;
obs_sceneitem_get_info(sceneitem, &info);
auto filter = obs_source_get_filter_by_name(data->source, "Mp4Alpha");
if (!filter)
{
filter = obs_source_create("mp4_alpha_filter", "Mp4Alpha", NULL, nullptr);
}
OBSDataAutoRelease curr_settings1 = obs_source_get_settings(filter);
if (ovi.base_width > ovi.base_height)
{
uint32_t targetWidth = 750 / 1334.0 * ovi.base_height;
info.pos.x = (ovi.base_width - targetWidth) / 2;
info.pos.y = 0;
obs_data_set_int(curr_settings1, "cx", targetWidth);
obs_data_set_int(curr_settings1, "cy", ovi.base_height);
}
else
{
uint32_t targetHeight = ovi.base_width / (750 / 1334.0);
info.pos.x = 0;
info.pos.y = (ovi.base_height - targetHeight) / 2;
obs_data_set_int(curr_settings1, "cx", ovi.base_width);
obs_data_set_int(curr_settings1, "cy", targetHeight);
}
obs_sceneitem_set_info(sceneitem, &info);
obs_source_update(filter, curr_settings1);
}
//播放有滤镜的媒体源
void OBSBasic::giftPlay(QListWidgetItem *item)
{
//读取自定义qt控件存储的媒体source中对应的MP3文件路径mp3Path和MP4文件路径mp4Path ,请自行修改
auto mp3Path = item->data(Qt::UserRole).toString();
auto mp4Path = item->data(Qt::UserRole + 1).toString();
//自己添加的source名称
const char *name = "mp4alpha";
const char *id = "ffmpeg_source";
const char *v_id = obs_get_latest_input_type_id(id);
OBSScene scene = GetCurrentScene();
if (!scene)
return;
OBSSourceAutoRelease source = obs_get_source_by_name(name);
//如果已创建source
if (source) {
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
//设置source属性
obs_data_set_string(curr_settings, "local_file", QT_TO_UTF8(mp4Path));
obs_source_update(source, curr_settings);
auto senceItem = obs_scene_find_source(scene, name);
//如果souce在源管理器中存在
if (senceItem) {
obs_video_info ovi;
obs_get_video_info(&ovi);
obs_transform_info info;
obs_sceneitem_get_info(senceItem , &info);
//获取播放透明通道alpha的滤镜
auto filter = obs_source_get_filter_by_name( source, "Mp4Alpha");
if (!filter) {
filter = obs_source_create( "mp4_alpha_filter", "Mp4Alpha", NULL, nullptr);
}
//根据视口大小设置滤镜属性
OBSDataAutoRelease curr_settings1 = obs_source_get_settings(filter);
if (ovi.base_width > ovi.base_height)
{
//MP4资源默认的宽高像素
uint32_t targetWidth = 750 / 1334.0 * ovi.base_height;
info.pos.x = (ovi.base_width - targetWidth) / 2;
info.pos.y = 0;
obs_data_set_int(curr_settings1, "cx", targetWidth);
obs_data_set_int( curr_settings1, "cy", ovi.base_height);
}
else
{
uint32_t targetHeight = ovi.base_width / (750 / 1334.0);
info.pos.x = 0;
info.pos.y = (ovi.base_height - targetHeight) / 2;
obs_data_set_int( curr_settings1, "cx", ovi.base_width);
obs_data_set_int(curr_settings1, "cy", targetHeight);
}
obs_sceneitem_set_info(senceItem, &info);
obs_source_update(filter, curr_settings1);
//获取媒体源播放状态
obs_media_state state = obs_source_media_get_state(source);
switch (state) {
case OBS_MEDIA_STATE_PLAYING:
obs_source_media_stop(source);
break;
case OBS_MEDIA_STATE_NONE:
case OBS_MEDIA_STATE_OPENING:
case OBS_MEDIA_STATE_BUFFERING:
case OBS_MEDIA_STATE_PAUSED:
case OBS_MEDIA_STATE_STOPPED:
case OBS_MEDIA_STATE_ENDED:
obs_source_media_restart(source);
break;
case OBS_MEDIA_STATE_ERROR:
break;
default:
break;
}
}
else
{
//如果souce在源管理器中不存在
AddSourceData data;
data.source = source;
data.visible = true;
obs_enter_graphics();
obs_scene_atomic_update(scene, AddSourceEx, &data);
obs_leave_graphics();
/* set monitoring if source monitors by default */
uint32_t flags = obs_source_get_output_flags(source);
if ((flags & OBS_SOURCE_MONITOR_BY_DEFAULT) != 0)
{
obs_source_set_monitoring_type( source, OBS_MONITORING_TYPE_MONITOR_ONLY);
}
SetSourceMixerHidden(source, true);
obs_source_set_hidden(source, true);
flags |= OBS_SOURCE_CAP_DISABLED;
obs_source_set_flags(source, flags);
}
}
else
{
//如果未创建source
source = obs_source_create(v_id, name, NULL, nullptr);
if (source) {
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
//设置source属性
obs_data_set_string(curr_settings, "local_file", QT_TO_UTF8(mp4Path));
obs_data_set_bool(curr_settings, "restart_on_activate", false);
obs_source_update(source, curr_settings);
auto filter = obs_source_get_filter_by_name( source, "Mp4Alpha");
if (!filter) {
filter = obs_source_create( "mp4_alpha_filter", "Mp4Alpha", NULL, nullptr);
}
//设置滤镜
OBSDataAutoRelease curr_settings1 = obs_source_get_settings(filter);
obs_data_set_bool(curr_settings1, "relative", false);
obs_data_set_int(curr_settings1, "left", 0);
obs_data_set_int(curr_settings1, "top", 0);
obs_data_set_int(curr_settings1, "right", 0);
obs_data_set_int(curr_settings1, "bottom", 0);
auto senceItem = obs_scene_find_source(scene, name);
obs_video_info ovi;
obs_get_video_info(&ovi);
obs_transform_info info;
obs_sceneitem_get_info(senceItem, &info);
if (ovi.base_width > ovi.base_height)
{
uint32_t targetWidth = 750 / 1334.0 * ovi.base_height;
obs_data_set_int(curr_settings1, "cx", targetWidth);
obs_data_set_int(curr_settings1, "cy", ovi.base_height);
}
else
{
uint32_t targetHeight = ovi.base_width / (750 / 1334.0);
obs_data_set_int(curr_settings1, "cx", ovi.base_width);
obs_data_set_int(curr_settings1, "cy", targetHeight);
}
obs_source_update(filter, curr_settings1);
//为媒体源添加滤镜
obs_source_filter_add(source, filter);
AddSourceData data;
data.source = source;
data.visible = true;
obs_enter_graphics();
obs_scene_atomic_update(scene, AddSourceEx, &data);
obs_leave_graphics();
/* set monitoring if source monitors by default */
uint32_t flags = obs_source_get_output_flags(source);
//取消监听,防止切换场景时自动播放
if ((flags & OBS_SOURCE_MONITOR_BY_DEFAULT) != 0)
{
obs_source_set_monitoring_type( source, OBS_MONITORING_TYPE_MONITOR_ONLY);
}
//隐藏混合
SetSourceMixerHidden(source, true);
//源不可见
obs_source_set_hidden(source, true);
flags &= OBS_SOURCE_CAP_DISABLED;
//Source type is currently disabled and should not be shown to the user
obs_source_set_flags(source, flags);
}
}
name = "mp3alpha";
source = obs_get_source_by_name(name);
if (source)
{
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
obs_data_set_string(curr_settings, "local_file", QT_TO_UTF8(mp3Path));
obs_source_update(source, curr_settings);
auto senceItem = obs_scene_find_source(scene, name);
if (senceItem)
{
obs_media_state state = obs_source_media_get_state(source);
switch (state) {
case OBS_MEDIA_STATE_PLAYING:
obs_source_media_stop(source);
break;
case OBS_MEDIA_STATE_NONE:
case OBS_MEDIA_STATE_OPENING:
case OBS_MEDIA_STATE_BUFFERING:
case OBS_MEDIA_STATE_PAUSED:
case OBS_MEDIA_STATE_STOPPED:
case OBS_MEDIA_STATE_ENDED:
obs_source_media_restart(source);
break;
case OBS_MEDIA_STATE_ERROR:
break;
default:
break;
}
}
else
{
AddSourceData data;
data.source = source;
data.visible = false;
obs_enter_graphics();
obs_scene_atomic_update(scene, AddSourceEx, &data);
obs_leave_graphics();
/* set monitoring if source monitors by default */
uint32_t flags = obs_source_get_output_flags(source);
if ((flags & OBS_SOURCE_MONITOR_BY_DEFAULT) != 0)
{
obs_source_set_monitoring_type( source, OBS_MONITORING_TYPE_MONITOR_ONLY);
}
SetSourceMixerHidden(source, true);
obs_source_set_hidden(source, true);
flags |= OBS_SOURCE_CAP_DISABLED;
obs_source_set_flags(source, flags);
}
}
else
{
source = obs_source_create(v_id, name, NULL, nullptr);
if (source)
{
OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
obs_data_set_string(curr_settings, "local_file", QT_TO_UTF8(mp3Path));
obs_data_set_bool(curr_settings, "restart_on_activate", false);
obs_source_update(source, curr_settings);
AddSourceData data;
data.source = source;
data.visible = false;
obs_enter_graphics();
obs_scene_atomic_update(scene, AddSourceEx, &data);
obs_leave_graphics();
/* set monitoring if source monitors by default */
uint32_t flags = obs_source_get_output_flags(source);
if ((flags & OBS_SOURCE_MONITOR_BY_DEFAULT) != 0) {
obs_source_set_monitoring_type( source, OBS_MONITORING_TYPE_MONITOR_ONLY);
}
SetSourceMixerHidden(source, true);
obs_source_set_hidden(source, true);
flags |= OBS_SOURCE_CAP_DISABLED;
obs_source_set_flags(source, flags);
}
}
}
说明:后续补充创建源及创建滤镜及如何让源管理界面中不显示