New upstream version 23.2.1+dfsg1

This commit is contained in:
Simon Chopin 2019-07-27 14:47:10 +02:00
parent cdc9a9fc87
commit b14f9eae6d
1017 changed files with 37232 additions and 11111 deletions

View file

@ -1 +1,2 @@
add_subdirectory(decklink-output-ui)
add_subdirectory(frontend-tools)

View file

@ -0,0 +1,61 @@
project(decklink-output-ui)
if(APPLE)
find_library(COCOA Cocoa)
include_directories(${COCOA})
endif()
if(UNIX AND NOT APPLE)
find_package(X11 REQUIRED)
link_libraries(${X11_LIBRARIES})
include_directories(${X11_INCLUDE_DIR})
endif()
set(decklink-ouput-ui_HEADERS
${decklink-ouput-ui_HEADERS}
../../properties-view.hpp
../../properties-view.moc.hpp
../../vertical-scroll-area.hpp
../../double-slider.hpp
../../slider-ignorewheel.hpp
../../combobox-ignorewheel.hpp
../../spinbox-ignorewheel.hpp
./DecklinkOutputUI.h
decklink-ui-main.h
)
set(decklink-ouput-ui_SOURCES
${decklink-ouput-ui_SOURCES}
../../properties-view.cpp
../../vertical-scroll-area.cpp
../../double-slider.cpp
../../slider-ignorewheel.cpp
../../combobox-ignorewheel.cpp
../../spinbox-ignorewheel.cpp
./DecklinkOutputUI.cpp
decklink-ui-main.cpp
)
set(decklink-ouput-ui_UI
${decklink-ouput-ui_UI}
forms/output.ui
)
if(APPLE)
set(decklink-ouput-ui_PLATFORM_LIBS
${COCOA})
endif()
qt5_wrap_ui(decklink-ouput-ui_UI_HEADERS
${decklink-ouput-ui_UI})
add_library(decklink-ouput-ui MODULE
${decklink-ouput-ui_HEADERS}
${decklink-ouput-ui_SOURCES}
${decklink-ouput-ui_UI_HEADERS}
)
target_link_libraries(decklink-ouput-ui
${frontend-tools_PLATFORM_LIBS}
obs-frontend-api
Qt5::Widgets
libobs)
install_obs_plugin_with_data(decklink-ouput-ui data)

View file

@ -0,0 +1,139 @@
#include "DecklinkOutputUI.h"
#include <obs-module.h>
#include <util/platform.h>
#include <util/util.hpp>
#include "decklink-ui-main.h"
DecklinkOutputUI::DecklinkOutputUI(QWidget *parent)
: QDialog(parent),
ui(new Ui_Output)
{
ui->setupUi(this);
setSizeGripEnabled(true);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
propertiesView = nullptr;
previewPropertiesView = nullptr;
connect(ui->startOutput, SIGNAL(released()), this, SLOT(StartOutput()));
connect(ui->stopOutput, SIGNAL(released()), this, SLOT(StopOutput()));
connect(ui->startPreviewOutput, SIGNAL(released()), this, SLOT(StartPreviewOutput()));
connect(ui->stopPreviewOutput, SIGNAL(released()), this, SLOT(StopPreviewOutput()));
}
void DecklinkOutputUI::ShowHideDialog()
{
SetupPropertiesView();
SetupPreviewPropertiesView();
setVisible(!isVisible());
}
void DecklinkOutputUI::SetupPropertiesView()
{
if (propertiesView)
delete propertiesView;
obs_data_t *settings = obs_data_create();
OBSData data = load_settings();
if (data)
obs_data_apply(settings, data);
propertiesView = new OBSPropertiesView(settings,
"decklink_output",
(PropertiesReloadCallback) obs_get_output_properties,
170);
ui->propertiesLayout->addWidget(propertiesView);
obs_data_release(settings);
connect(propertiesView, SIGNAL(Changed()), this, SLOT(PropertiesChanged()));
}
void DecklinkOutputUI::SaveSettings()
{
BPtr<char> modulePath = obs_module_get_config_path(obs_current_module(), "");
os_mkdirs(modulePath);
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
"decklinkOutputProps.json");
obs_data_t *settings = propertiesView->GetSettings();
if (settings)
obs_data_save_json_safe(settings, path, "tmp", "bak");
}
void DecklinkOutputUI::SetupPreviewPropertiesView()
{
if (previewPropertiesView)
delete previewPropertiesView;
obs_data_t *settings = obs_data_create();
OBSData data = load_preview_settings();
if (data)
obs_data_apply(settings, data);
previewPropertiesView = new OBSPropertiesView(settings,
"decklink_output",
(PropertiesReloadCallback) obs_get_output_properties,
170);
ui->previewPropertiesLayout->addWidget(previewPropertiesView);
obs_data_release(settings);
connect(previewPropertiesView, SIGNAL(Changed()), this, SLOT(PreviewPropertiesChanged()));
}
void DecklinkOutputUI::SavePreviewSettings()
{
char *modulePath = obs_module_get_config_path(obs_current_module(), "");
os_mkdirs(modulePath);
char *path = obs_module_get_config_path(obs_current_module(),
"decklinkPreviewOutputProps.json");
obs_data_t *settings = previewPropertiesView->GetSettings();
if (settings)
obs_data_save_json_safe(settings, path, "tmp", "bak");
}
void DecklinkOutputUI::StartOutput()
{
SaveSettings();
output_start();
}
void DecklinkOutputUI::StopOutput()
{
output_stop();
}
void DecklinkOutputUI::PropertiesChanged()
{
SaveSettings();
}
void DecklinkOutputUI::StartPreviewOutput()
{
SavePreviewSettings();
preview_output_start();
}
void DecklinkOutputUI::StopPreviewOutput()
{
preview_output_stop();
}
void DecklinkOutputUI::PreviewPropertiesChanged()
{
SavePreviewSettings();
}

View file

@ -0,0 +1,34 @@
#pragma once
#include <QDialog>
#include "ui_output.h"
#include "../../UI/properties-view.hpp"
class DecklinkOutputUI : public QDialog {
Q_OBJECT
private:
OBSPropertiesView *propertiesView;
OBSPropertiesView *previewPropertiesView;
public slots:
void StartOutput();
void StopOutput();
void PropertiesChanged();
void StartPreviewOutput();
void StopPreviewOutput();
void PreviewPropertiesChanged();
public:
std::unique_ptr<Ui_Output> ui;
DecklinkOutputUI(QWidget *parent);
void ShowHideDialog();
void SetupPropertiesView();
void SaveSettings();
void SetupPreviewPropertiesView();
void SavePreviewSettings();
};

View file

@ -0,0 +1,286 @@
#include <obs-module.h>
#include <obs-frontend-api.h>
#include <QMainWindow>
#include <QAction>
#include <util/util.hpp>
#include <util/platform.h>
#include <media-io/video-io.h>
#include <media-io/video-frame.h>
#include "DecklinkOutputUI.h"
#include "../../../plugins/decklink/const.h"
OBS_DECLARE_MODULE()
OBS_MODULE_USE_DEFAULT_LOCALE("decklink-output-ui", "en-US")
DecklinkOutputUI *doUI;
bool main_output_running = false;
bool preview_output_running = false;
obs_output_t *output;
struct preview_output {
bool enabled;
obs_source_t *current_source;
obs_output_t *output;
video_t *video_queue;
gs_texrender_t *texrender;
gs_stagesurf_t *stagesurface;
uint8_t *video_data;
uint32_t video_linesize;
obs_video_info ovi;
};
static struct preview_output context = {0};
OBSData load_settings()
{
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
"decklinkOutputProps.json");
BPtr<char> jsonData = os_quick_read_utf8_file(path);
if (!!jsonData) {
obs_data_t *data = obs_data_create_from_json(jsonData);
OBSData dataRet(data);
obs_data_release(data);
return dataRet;
}
return nullptr;
}
void output_start()
{
if (!main_output_running) {
OBSData settings = load_settings();
if (settings != nullptr) {
output = obs_output_create("decklink_output",
"decklink_output", settings, NULL);
obs_output_start(output);
obs_data_release(settings);
main_output_running = true;
}
}
}
void output_stop()
{
if (main_output_running) {
obs_output_stop(output);
obs_output_release(output);
main_output_running = false;
}
}
OBSData load_preview_settings()
{
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
"decklinkPreviewOutputProps.json");
BPtr<char> jsonData = os_quick_read_utf8_file(path);
if (!!jsonData) {
obs_data_t *data = obs_data_create_from_json(jsonData);
OBSData dataRet(data);
obs_data_release(data);
return dataRet;
}
return nullptr;
}
void on_preview_scene_changed(enum obs_frontend_event event, void *param);
void render_preview_source(void *param, uint32_t cx, uint32_t cy);
void preview_output_start()
{
if (!preview_output_running) {
OBSData settings = load_preview_settings();
if (settings != nullptr) {
context.output = obs_output_create("decklink_output",
"decklink_preview_output", settings, NULL);
obs_get_video_info(&context.ovi);
uint32_t width = context.ovi.base_width;
uint32_t height = context.ovi.base_height;
obs_enter_graphics();
context.texrender = gs_texrender_create(GS_BGRA, GS_ZS_NONE);
context.stagesurface = gs_stagesurface_create(width, height, GS_BGRA);
obs_leave_graphics();
const video_output_info *mainVOI = video_output_get_info(obs_get_video());
video_output_info vi = {0};
vi.format = VIDEO_FORMAT_BGRA;
vi.width = width;
vi.height = height;
vi.fps_den = context.ovi.fps_den;
vi.fps_num = context.ovi.fps_num;
vi.cache_size = 16;
vi.colorspace = mainVOI->colorspace;
vi.range = mainVOI->range;
vi.name = "decklink_preview_output";
video_output_open(&context.video_queue, &vi);
obs_frontend_add_event_callback(on_preview_scene_changed, &context);
if (obs_frontend_preview_program_mode_active()) {
context.current_source = obs_frontend_get_current_preview_scene();
} else {
context.current_source = obs_frontend_get_current_scene();
}
obs_add_main_render_callback(render_preview_source, &context);
obs_output_set_media(context.output, context.video_queue, obs_get_audio());
obs_output_start(context.output);
preview_output_running = true;
}
}
}
void preview_output_stop()
{
if (preview_output_running) {
obs_output_stop(context.output);
video_output_stop(context.video_queue);
obs_remove_main_render_callback(render_preview_source, &context);
obs_frontend_remove_event_callback(on_preview_scene_changed, &context);
obs_source_release(context.current_source);
obs_enter_graphics();
gs_stagesurface_destroy(context.stagesurface);
gs_texrender_destroy(context.texrender);
obs_leave_graphics();
video_output_close(context.video_queue);
preview_output_running = false;
}
}
void on_preview_scene_changed(enum obs_frontend_event event, void *param)
{
auto ctx = (struct preview_output*)param;
switch (event) {
case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED:
case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED:
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_preview_scene();
break;
case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED:
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_scene();
break;
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
if (!obs_frontend_preview_program_mode_active()) {
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_scene();
}
break;
default:
break;
}
}
void render_preview_source(void *param, uint32_t cx, uint32_t cy)
{
auto ctx = (struct preview_output*)param;
if (!ctx->current_source) return;
uint32_t width = obs_source_get_base_width(ctx->current_source);
uint32_t height = obs_source_get_base_height(ctx->current_source);
gs_texrender_reset(ctx->texrender);
if (gs_texrender_begin(ctx->texrender, width, height)) {
struct vec4 background;
vec4_zero(&background);
gs_clear(GS_CLEAR_COLOR, &background, 0.0f, 0);
gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f);
gs_blend_state_push();
gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO);
obs_source_video_render(ctx->current_source);
gs_blend_state_pop();
gs_texrender_end(ctx->texrender);
struct video_frame output_frame;
if (video_output_lock_frame(ctx->video_queue, &output_frame, 1, os_gettime_ns()))
{
gs_stage_texture(ctx->stagesurface, gs_texrender_get_texture(ctx->texrender));
if (gs_stagesurface_map(ctx->stagesurface, &ctx->video_data, &ctx->video_linesize)) {
uint32_t linesize = output_frame.linesize[0];
for (uint32_t i = 0; i < ctx->ovi.base_height; i++) {
uint32_t dst_offset = linesize * i;
uint32_t src_offset = ctx->video_linesize * i;
memcpy(output_frame.data[0] + dst_offset,
ctx->video_data + src_offset,
linesize);
}
gs_stagesurface_unmap(ctx->stagesurface);
ctx->video_data = nullptr;
}
video_output_unlock_frame(ctx->video_queue);
}
}
}
void addOutputUI(void)
{
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("Decklink Output"));
QMainWindow *window = (QMainWindow*)obs_frontend_get_main_window();
obs_frontend_push_ui_translation(obs_module_get_string);
doUI = new DecklinkOutputUI(window);
obs_frontend_pop_ui_translation();
auto cb = []() {
doUI->ShowHideDialog();
};
action->connect(action, &QAction::triggered, cb);
}
static void OBSEvent(enum obs_frontend_event event, void *)
{
if (event == OBS_FRONTEND_EVENT_FINISHED_LOADING) {
OBSData settings = load_settings();
if (settings && obs_data_get_bool(settings, "auto_start"))
output_start();
OBSData previewSettings = load_preview_settings();
if (previewSettings && obs_data_get_bool(previewSettings, "auto_start"))
preview_output_start();
}
}
bool obs_module_load(void)
{
addOutputUI();
obs_frontend_add_event_callback(OBSEvent, nullptr);
return true;
}

View file

@ -0,0 +1,8 @@
#pragma once
void output_start();
void output_stop();
OBSData load_settings();
void preview_output_start();
void preview_output_stop();
OBSData load_preview_settings();

View file

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Output</class>
<widget class="QDialog" name="Output">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>785</width>
<height>497</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Decklink Output</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<property name="modal">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Output</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="propertiesLayout"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>-1</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="startOutput">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopOutput">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Preview Output</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="previewPropertiesLayout"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="startPreviewOutput">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopPreviewOutput">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Keyer output requires RGB mode in advanced settings.</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -28,6 +28,9 @@ set(frontend-tools_HEADERS
../../horizontal-scroll-area.hpp
../../vertical-scroll-area.hpp
../../double-slider.hpp
../../slider-ignorewheel.hpp
../../combobox-ignorewheel.hpp
../../spinbox-ignorewheel.hpp
)
set(frontend-tools_SOURCES
${frontend-tools_SOURCES}
@ -38,6 +41,9 @@ set(frontend-tools_SOURCES
../../horizontal-scroll-area.cpp
../../vertical-scroll-area.cpp
../../double-slider.cpp
../../slider-ignorewheel.cpp
../../combobox-ignorewheel.cpp
../../spinbox-ignorewheel.cpp
)
set(frontend-tools_UI
${frontend-tools_UI}

View file

@ -89,6 +89,8 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
lock_guard<mutex> lock(switcher->m);
switcher->Prune();

View file

@ -249,8 +249,9 @@ STDMETHODIMP CaptionStream::Stat(STATSTG *stg, DWORD flag)
stg->cbSize.QuadPart = (ULONGLONG)buf->size;
if (flag == STATFLAG_DEFAULT) {
stg->pwcsName = (wchar_t*)CoTaskMemAlloc(sizeof(stat_name));
memcpy(stg->pwcsName, stat_name, sizeof(stat_name));
size_t byte_size = (wcslen(stat_name) + 1) * sizeof(wchar_t);
stg->pwcsName = (wchar_t*)CoTaskMemAlloc(byte_size);
memcpy(stg->pwcsName, stat_name, byte_size);
}
return S_OK;

View file

@ -90,6 +90,8 @@ CaptionsDialog::CaptionsDialog(QWidget *parent) :
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
auto cb = [this] (obs_source_t *source)
{
uint32_t caps = obs_source_get_output_flags(source);

View file

@ -0,0 +1,42 @@
SceneSwitcher="مبدل المَشاهِد التلقائي"
SceneSwitcher.OnNoMatch="عندما لا تتطابق أي نافذة:"
SceneSwitcher.OnNoMatch.DontSwitch="لا تقم بالتبديل"
SceneSwitcher.OnNoMatch.SwitchTo="التبديل إلى:"
SceneSwitcher.CheckInterval="التأكد من عنوان النافذة النشطة كل:"
SceneSwitcher.ActiveOrNotActive="حالة مبدل المشاهد:"
InvalidRegex.Title="تعبير نمطي غير صحيح"
InvalidRegex.Text="التعبير النمطي الذي أدخلته غير صحيح."
Active="مفعّل"
Inactive="غير مُفعّل"
Start="ابدأ"
Stop="ايقاف"
Captions="ترجمة فورية (تجريبي)"
Captions.AudioSource="مصدر الصوت"
Captions.CurrentSystemLanguage="لغة النظام الحالية (%1)"
Captions.Provider="موفر الخدمة"
Captions.Error.GenericFail="فشل في تشغيل الترجمة الفورية"
OutputTimer="مؤقِّت الإخراج"
OutputTimer.Stream="إيقاف البث بعد:"
OutputTimer.Record="إيقاف التسجيل بعد:"
OutputTimer.Stream.StoppingIn="سيتم إيقاف البث بعد:"
OutputTimer.Record.StoppingIn="سيتم إيقاف التسجيل بعد:"
OutputTimer.Stream.EnableEverytime="تفعيل مؤقِّت البث في كل مرة"
OutputTimer.Record.EnableEverytime="تفعيل مؤقِّت التسجيل في كل مرة"
Scripts="سكريبتات"
LoadedScripts="السكريبتات المحملة"
AddScripts="إضافة سكريبت"
RemoveScripts="إزالة السكريبت"
ReloadScripts="إعادة تحميل السكربتات"
PythonSettings="إعدادات بايثون"
PythonSettings.PythonInstallPath32bit="مسار تثبيت بايثون (32 بت)"
PythonSettings.PythonInstallPath64bit="مسار تثبيت بايثون (64 بت)"
PythonSettings.BrowsePythonPath="استعراض مسار البايثون"
ScriptLogWindow="سجل السكريبت"
Description="الوصف"
FileFilter.ScriptFiles="ملفات السكريبت"
FileFilter.AllFiles="كافة الملفات"

View file

@ -0,0 +1,35 @@
SceneSwitcher="Автоматичен превключвател на сцени"
SceneSwitcher.OnNoMatch.DontSwitch="Не превключвай"
SceneSwitcher.OnNoMatch.SwitchTo="Превключи на:"
SceneSwitcher.CheckInterval="Проверка название на активния прозорец всеки:"
SceneSwitcher.ActiveOrNotActive="Превключвателят на сцени е:"
Active="Активен"
Inactive="Изключен"
Start="Начало"
Stop="Край"
Captions="Надписи (експериментално)"
Captions.AudioSource="Аудио източник"
Captions.CurrentSystemLanguage="Текущ основен език (%1)"
Captions.Provider="Доставчик"
Captions.Error.GenericFail="Неуспешно зареждане на надписи"
OutputTimer.Stream="Прекъсни излъчването след:"
OutputTimer.Record="Прекъсни записването след:"
OutputTimer.Stream.StoppingIn="Излъчването ще спре след:"
OutputTimer.Record.StoppingIn="Записването ще спре след:"
OutputTimer.Stream.EnableEverytime="Показвай брояча на излъчването всеки път"
Scripts="Скриптове"
LoadedScripts="Заредени скриптове"
AddScripts="Добавяне скриптове"
RemoveScripts="Премахване скриптове"
ReloadScripts="Опресняване скриптове"
PythonSettings="Настройки Python"
PythonSettings.PythonInstallPath32bit="Път за инсталация на Python (32 бита)"
PythonSettings.PythonInstallPath64bit="Път за инсталация на Python (64 бита)"
ScriptLogWindow="Записи на скриптове"
Description="Описание"
FileFilter.AllFiles="Всички файлове"

View file

@ -1,9 +1,9 @@
SceneSwitcher="Automatisk sceneomskifter"
SceneSwitcher="Automatisk sceneskifter"
SceneSwitcher.OnNoMatch="Når intet vindue matcher:"
SceneSwitcher.OnNoMatch.DontSwitch="Skift ikke"
SceneSwitcher.OnNoMatch.SwitchTo="Skift til:"
SceneSwitcher.CheckInterval="Kontroller aktivt vinduestitel hvert:"
SceneSwitcher.ActiveOrNotActive="Sceneomskifter er:"
SceneSwitcher.CheckInterval="Tjek aktiv vinduestitel hver:"
SceneSwitcher.ActiveOrNotActive="Sceneskifter er:"
InvalidRegex.Title="Ugyldigt regulært udtryk"
InvalidRegex.Text="Det af dig angivne regulære udtryk er ugyldigt."
Active="Aktiv"
@ -11,19 +11,19 @@ Inactive="Inaktiv"
Start="Start"
Stop="Stop"
Captions="Undertekster (eksperimentel)"
Captions="Billedtekster (eksperimentel)"
Captions.AudioSource="Lydkilde"
Captions.CurrentSystemLanguage="Aktuelt systemsprog (%1)"
Captions.Provider="Leverandør"
Captions.Error.GenericFail="Kunne ikke starte tekster"
Captions.Error.GenericFail="Kunne ikke starte billedtekster"
OutputTimer="Output-timer"
OutputTimer="Outputtimer"
OutputTimer.Stream="Stands streaming efter:"
OutputTimer.Record="Stands optagelse efter:"
OutputTimer.Stream.StoppingIn="Streaming standser om:"
OutputTimer.Record.StoppingIn="Streaming standser om:"
OutputTimer.Stream.EnableEverytime="Aktivér streaming-timer hver gang"
OutputTimer.Record.EnableEverytime="Aktivér optage-timer hver gang"
OutputTimer.Record.StoppingIn="Optagelse standser om:"
OutputTimer.Stream.EnableEverytime="Aktivér streamingtimer hver gang"
OutputTimer.Record.EnableEverytime="Aktivér optagetimer hver gang"
Scripts="Scripts"
LoadedScripts="Indlæste scripts"
@ -33,7 +33,7 @@ ReloadScripts="Genindlæs scripts"
PythonSettings="Python-indstillinger"
PythonSettings.PythonInstallPath32bit="Python-installationssti (32bit)"
PythonSettings.PythonInstallPath64bit="Python-installationssti (64bit)"
PythonSettings.BrowsePythonPath="Gennemse Python-sti"
PythonSettings.BrowsePythonPath="Find Python-sti"
ScriptLogWindow="Scriptlog"
Description="Beskrivelse"

View file

@ -8,8 +8,8 @@ InvalidRegex.Title="Ungültiger regulärer Ausdruck"
InvalidRegex.Text="Der reguläre Ausdruck, den Sie eingegeben haben, ist ungültig."
Active="Aktiv"
Inactive="Inaktiv"
Start="Start"
Stop="Stop"
Start="Starten"
Stop="Stoppen"
Captions="Untertitel (experimentell)"
Captions.AudioSource="Audioquelle"
@ -22,8 +22,8 @@ OutputTimer.Stream="Stoppe Stream nach:"
OutputTimer.Record="Stoppe Aufnahme nach:"
OutputTimer.Stream.StoppingIn="Stream stoppt in:"
OutputTimer.Record.StoppingIn="Aufnahme stoppt in:"
OutputTimer.Stream.EnableEverytime="Streaming-Timer jedes Mal aktivieren"
OutputTimer.Record.EnableEverytime="Aufnahme-Timer jedes Mal aktivieren"
OutputTimer.Stream.EnableEverytime="Streamingtimer jedes Mal aktivieren"
OutputTimer.Record.EnableEverytime="Aufnahmetimer jedes Mal aktivieren"
Scripts="Skripte"
LoadedScripts="Geladene Skripte"
@ -31,8 +31,8 @@ AddScripts="Skripte hinzufügen"
RemoveScripts="Skripte entfernen"
ReloadScripts="Skripte neu laden"
PythonSettings="Python-Einstellungen"
PythonSettings.PythonInstallPath32bit="Python Installationspfad (32bit)"
PythonSettings.PythonInstallPath64bit="Python Installationspfad (64bit)"
PythonSettings.PythonInstallPath32bit="Python-Installationspfad (32bit)"
PythonSettings.PythonInstallPath64bit="Python-Installationspfad (64bit)"
PythonSettings.BrowsePythonPath="Python-Pfad öffnen"
ScriptLogWindow="Skriptprotokoll"
Description="Beschreibung"

View file

@ -25,11 +25,11 @@ OutputTimer.Record.StoppingIn="Finalizando grabación en:"
OutputTimer.Stream.EnableEverytime="Activar temporizador en cada transmisión"
OutputTimer.Record.EnableEverytime="Activar temporizador en cada grabación"
Scripts="Guion"
LoadedScripts="Guiones cargados"
AddScripts="Agregar Guiones"
RemoveScripts="Quitar Guiones"
ReloadScripts="Recargar Guiones"
Scripts="Scripts"
LoadedScripts="Scripts Cargados"
AddScripts="Añadir Scripts"
RemoveScripts="Eliminar Scripts"
ReloadScripts="Recargar Scripts"
PythonSettings="Configuración de Python"
PythonSettings.PythonInstallPath32bit="Dirección de la instalación de Python (32bit)"
PythonSettings.PythonInstallPath64bit="Dirección de la instalación de Python (64bit)"
@ -37,6 +37,6 @@ PythonSettings.BrowsePythonPath="Buscar Ruta de Phyton"
ScriptLogWindow="Registro de secuencia de comandos"
Description="Descripción"
FileFilter.ScriptFiles="Archivos de Guiones"
FileFilter.ScriptFiles="Archivos de Script"
FileFilter.AllFiles="Todos los archivos"

View file

@ -0,0 +1,25 @@
SceneSwitcher.OnNoMatch="وقتی هیچ پنجره‌ای همخوانی نداشت:"
SceneSwitcher.OnNoMatch.DontSwitch="سوییچ نکن"
SceneSwitcher.OnNoMatch.SwitchTo="سویچ کن به:"
Active="فعال"
Inactive="غیر فعال"
Start="شروع"
Stop="توقف"
OutputTimer.Stream.EnableEverytime="هربار زمان سنج پخش جریانی را فعال کنید"
OutputTimer.Record.EnableEverytime="هربار زمان سنج ضبط را فعال کنید"
Scripts="اسکریپت ها"
LoadedScripts="اسکریپت های بارگیری شده"
AddScripts="اضافه کردن اسکریپت ها"
RemoveScripts="پاک کردن اسکریپت ها"
ReloadScripts="بارگیری مجدد اسکریپت ها"
PythonSettings="تنظیمات پایتون"
PythonSettings.BrowsePythonPath="مرور مسیر پایتون"
ScriptLogWindow="اسکریپت نویسی"
Description="توضیحات"
FileFilter.ScriptFiles="فایل های اسکریپت"
FileFilter.AllFiles="همه‌ی فایل ها"

View file

@ -3,8 +3,8 @@ SceneSwitcher.OnNoMatch="Si aucune fenêtre ne correspond :"
SceneSwitcher.OnNoMatch.DontSwitch="Ne rien faire"
SceneSwitcher.OnNoMatch.SwitchTo="Basculer vers :"
SceneSwitcher.CheckInterval="Vérifier le titre de la fenêtre active toutes les :"
SceneSwitcher.ActiveOrNotActive="Etat du sélecteur automatique :"
InvalidRegex.Title="Expression invalide"
SceneSwitcher.ActiveOrNotActive="État du sélecteur automatique :"
InvalidRegex.Title="Expression régulière invalide"
InvalidRegex.Text="L'expression régulière saisie est invalide."
Active="Actif"
Inactive="Inactif"
@ -18,12 +18,12 @@ Captions.Provider="Sous-Titres"
Captions.Error.GenericFail="Impossible de démarrer les sous-titres"
OutputTimer="Minuterie des sorties"
OutputTimer.Stream="Arrêter le streaming dans :"
OutputTimer.Record="Arrêter l'enregistrement dans :"
OutputTimer.Stream="Arrêter le streaming après :"
OutputTimer.Record="Arrêter l'enregistrement après :"
OutputTimer.Stream.StoppingIn="Arrêt du streaming dans :"
OutputTimer.Record.StoppingIn="Arrêt de l'enregistrement dans :"
OutputTimer.Stream.EnableEverytime="Activer le minuteur automatiquement à chaque stream"
OutputTimer.Record.EnableEverytime="Activer le minuteur automatiquement à chaque enregistrement"
OutputTimer.Stream.EnableEverytime="Démarrer le minuteur automatiquement à chaque stream"
OutputTimer.Record.EnableEverytime="Démarrer le minuteur automatiquement à chaque enregistrement"
Scripts="Scripts"
LoadedScripts="Scripts chargés"
@ -33,7 +33,7 @@ ReloadScripts="Recharger les Scripts"
PythonSettings="Paramètres Python"
PythonSettings.PythonInstallPath32bit="Chemin dinstallation Python (32 bits)"
PythonSettings.PythonInstallPath64bit="Chemin dinstallation Python (64 bits)"
PythonSettings.BrowsePythonPath="Parcourir le chemin de Python"
PythonSettings.BrowsePythonPath="Localiser l'installation de Python"
ScriptLogWindow="Journal de script"
Description="Description"

View file

@ -16,7 +16,7 @@ Captions="Opisi (experimentalno)"
OutputTimer="Tempomat snimanja i emitovanja"
OutputTimer.Stream="Zaustavi emitovanje nakon:"
OutputTimer.Record="Zaustavi snimanje nakon:"
OutputTimer.Stream.StoppingIn="Prekidanje emitovanja za:"
OutputTimer.Stream.StoppingIn="Prekidanje emitiranja za:"
OutputTimer.Record.StoppingIn="Prekidanje snimanja za:"
OutputTimer.Stream.EnableEverytime="Omogući štopovanje emitovanja svaki put"
OutputTimer.Record.EnableEverytime="Omogući štopovanje snimanja svaki put"

View file

@ -1,4 +1,4 @@
SceneSwitcher="Cambia scena automatico"
SceneSwitcher="Cambio scena automatico"
SceneSwitcher.OnNoMatch="Quando nessuna finestra coincide:"
SceneSwitcher.OnNoMatch.DontSwitch="Non passare"
SceneSwitcher.OnNoMatch.SwitchTo="Passa a:"
@ -17,13 +17,13 @@ Captions.CurrentSystemLanguage="Lingua del sistema (%1)"
Captions.Provider="Sintetizzatore"
Captions.Error.GenericFail="Impossibile avviare i sottititoli"
OutputTimer="Timer di uscita"
OutputTimer.Stream="Termina diretta dopo:"
OutputTimer.Record="Termina registrazione dopo:"
OutputTimer.Stream.StoppingIn="La diretta terminerà in:"
OutputTimer.Record.StoppingIn="La registrazione terminerà in:"
OutputTimer.Stream.EnableEverytime="Abilita il timer per lo streaming ogni volta"
OutputTimer.Record.EnableEverytime="Abilita il timer per la registrazione ogni volta"
OutputTimer="Conto alla rovescia"
OutputTimer.Stream="Termina la diretta dopo:"
OutputTimer.Record="Termina la registrazione dopo:"
OutputTimer.Stream.StoppingIn="La diretta terminerà tra:"
OutputTimer.Record.StoppingIn="La registrazione terminerà tra:"
OutputTimer.Stream.EnableEverytime="Attiva il conto alla rovescia per le dirette ogni volta"
OutputTimer.Record.EnableEverytime="Attiva il conto alla rovescia per le registrazioni ogni volta"
Scripts="Script"
LoadedScripts="Script caricati"
@ -31,9 +31,9 @@ AddScripts="Aggiungi script"
RemoveScripts="Rimuovi script"
ReloadScripts="Ricarica script"
PythonSettings="Impostazioni di Python"
PythonSettings.PythonInstallPath32bit="Percorso d'installazione di Python (32bit)"
PythonSettings.PythonInstallPath64bit="Percorso d'installazione di Python (64bit)"
PythonSettings.BrowsePythonPath="Sfoglia Percorso Python"
PythonSettings.PythonInstallPath32bit="Percorso d'installazione di Python (32 bit)"
PythonSettings.PythonInstallPath64bit="Percorso d'installazione di Python (64 bit)"
PythonSettings.BrowsePythonPath="Sfoglia il percorso di Python"
ScriptLogWindow="Log degli script"
Description="Descrizione"

View file

@ -20,7 +20,7 @@ Captions.Error.GenericFail="წარწერების დადება
OutputTimer="ჩაწერის და ნაკადის წამზომი"
OutputTimer.Stream="ნაკადი გაეშვას არაუმეტეს:"
OutputTimer.Record="ჩაწერა გაგრძელდეს არაუმეტეს:"
OutputTimer.Stream.StoppingIn="ნაკადის შეჩერების დროა:"
OutputTimer.Stream.StoppingIn="ნაკადის შეწყვეტის დრო:"
OutputTimer.Record.StoppingIn="ჩაწერის შეწყვეტის დრო:"
OutputTimer.Stream.EnableEverytime="ნაკადის წამზომის ჩართვა ყოველ ჯერზე"
OutputTimer.Record.EnableEverytime="ჩაწერის წამზომის ჩართვა ყოველ ჯერზე"

View file

@ -0,0 +1,32 @@
SceneSwitcher.OnNoMatch.DontSwitch="Бүү соль"
SceneSwitcher.OnNoMatch.SwitchTo="Үүнрүү шилжүүл:"
Active="Идэвхтэй"
Inactive="Идэвхгүй"
Start="Эхлэх"
Stop="Зогсоох"
Captions.AudioSource="Аудио эх сурвалж"
Captions.CurrentSystemLanguage="Одоогийн системийн хэл (%1)"
Captions.Provider="Үйлчилгээ үзүүлэгч"
OutputTimer="Гаралтын цагийн тохируулга"
OutputTimer.Stream="Цацалтыг үүний дараа зогсоох:"
OutputTimer.Record="Бичлэгийг үүний дараа зогсоох:"
OutputTimer.Stream.StoppingIn="Урсгалыг зогсооход:"
OutputTimer.Record.StoppingIn="Бичлэгийг зогсооход:"
Scripts="Скриптүүд"
LoadedScripts="Уншигдсан скриптүүд"
AddScripts="Скрипт нэмэх"
RemoveScripts="Скрипт хасах"
ReloadScripts="Скрипт дахин унших"
PythonSettings="Python тохиргоо"
PythonSettings.PythonInstallPath32bit="Python суусан байрлал (32 бит)"
PythonSettings.PythonInstallPath64bit="Python суусан байрлал (64 бит)"
PythonSettings.BrowsePythonPath="Python-ы замыг заах"
ScriptLogWindow="Скриптийн тэмдэглэл"
Description="Тайлбар"
FileFilter.ScriptFiles="Скрипт файлууд"
FileFilter.AllFiles="Бүх файлууд"

View file

@ -1,4 +1,4 @@
SceneSwitcher="Automatyczne Przełączanie Scen"
SceneSwitcher="Automatyczne przełączanie scen"
SceneSwitcher.OnNoMatch="Gdy nie pasuje żadne okno:"
SceneSwitcher.OnNoMatch.DontSwitch="Nie przełączaj"
SceneSwitcher.OnNoMatch.SwitchTo="Przełącz na:"

View file

@ -14,6 +14,7 @@ Stop="Parar"
Captions="Legendas (Experimental)"
Captions.AudioSource="Fonte de audio"
Captions.CurrentSystemLanguage="Linguagem de Sistema Atual (%1)"
Captions.Provider="Fornecedor"
Captions.Error.GenericFail="Ocorreu um erro a iniciar legendas"
OutputTimer="Temporizador de saída"
@ -24,5 +25,15 @@ OutputTimer.Record.StoppingIn="A gravação irá parar em:"
OutputTimer.Stream.EnableEverytime="Ativar temporizador de transmissão sempre"
OutputTimer.Record.EnableEverytime="Ativar temporizador de gravação sempre"
Scripts="Scripts"
LoadedScripts="Scripts Carregados"
AddScripts="Adicionar Scripts"
RemoveScripts="Remover Scripts"
ReloadScripts="Recarregar Scripts"
PythonSettings="Definições do Python"
PythonSettings.PythonInstallPath32bit="Caminho da Instalação do Python (32bits)"
PythonSettings.PythonInstallPath64bit="Caminho da Instalação do Python (64bits)"
Description="Descrição"
FileFilter.AllFiles="Todos os Ficheiros"

View file

@ -1,18 +1,33 @@
SceneSwitcher="Schimbator automat de scenă"
SceneSwitcher="Schimbător automat de scene"
SceneSwitcher.OnNoMatch="Când nicio fereastră nu se potrivește:"
SceneSwitcher.OnNoMatch.DontSwitch="Nu schimba"
SceneSwitcher.OnNoMatch.SwitchTo="Schimbă la:"
SceneSwitcher.CheckInterval="Verifică titlul ferestrei active la fiecare:"
SceneSwitcher.ActiveOrNotActive="Schimbătorul de scene este:"
Active="Activ"
Inactive="Inactiv"
Start="Pornire"
Stop="Oprire"
Start="Pornește"
Stop="Oprește"
Captions="Subtitrări (experimentale)"
Captions.AudioSource="Sursa audio"
Captions.CurrentSystemLanguage="Limba curentă a sistemului (%1)"
Captions.CurrentSystemLanguage="Limba actuală a sistemului (%1)"
Captions.Provider="Furnizor"
OutputTimer.Record="Opriți inregistrarea dupa:"
OutputTimer.Record.StoppingIn="Oprire înregistrare în:"
OutputTimer.Record="Opriți înregistrarea după:"
OutputTimer.Stream.StoppingIn="Se oprește transmisiunea în:"
OutputTimer.Record.StoppingIn="Înregistrarea se oprește în:"
Scripts="Scripturi"
LoadedScripts="Scripturi încărcate"
AddScripts="Adaugă scripturi"
RemoveScripts="Elimină scripturi"
ReloadScripts="Reîncarcă scripturile"
PythonSettings="Setări Python"
PythonSettings.PythonInstallPath32bit="Calea instalării Python (32bit)"
PythonSettings.PythonInstallPath64bit="Calea instalării Python (64bit)"
PythonSettings.BrowsePythonPath="Răsfoiește calea Python"
ScriptLogWindow="Jurnalul scripturilor"
Description="Descriere"

View file

@ -17,10 +17,10 @@ Captions.CurrentSystemLanguage="Текущий язык системы (%1)"
Captions.Provider="Поставщик"
Captions.Error.GenericFail="Не удалось запустить субтитры"
OutputTimer="Таймер записи и трансляции"
OutputTimer.Stream="Завершить трансляцию через:"
OutputTimer="Таймер записи и стрима"
OutputTimer.Stream="Завершить стрим через:"
OutputTimer.Record="Завершить запись через:"
OutputTimer.Stream.StoppingIn="Трансляция будет завершена через:"
OutputTimer.Stream.StoppingIn="Стрим будет завершён через:"
OutputTimer.Record.StoppingIn="Запись будет завершена через:"
OutputTimer.Stream.EnableEverytime="Включать таймер трансляции каждый раз"
OutputTimer.Record.EnableEverytime="Включать таймер записи каждый раз"

View file

@ -25,5 +25,18 @@ OutputTimer.Record.StoppingIn="Nahrávanie za zastaví za:"
OutputTimer.Stream.EnableEverytime="Povoliť časovač streamovania zakaždým"
OutputTimer.Record.EnableEverytime="Zapnúť časovač nahrávania zakaždým"
Scripts="Skripty"
LoadedScripts="Načítané skripty"
AddScripts="Pridať skripty"
RemoveScripts="Odstrániť skripty"
ReloadScripts="Znovu-načítať skripty"
PythonSettings="Python nastavenia"
PythonSettings.PythonInstallPath32bit="Python inštalačná cesta (32bitová)"
PythonSettings.PythonInstallPath64bit="Python inštalačná cesta (64bitová)"
PythonSettings.BrowsePythonPath="Prehliadať cestu k Pythonu"
ScriptLogWindow="Log skriptu"
Description="Popis"
FileFilter.ScriptFiles="Súbory skriptu"
FileFilter.AllFiles="Všetky súbory"

View file

@ -11,14 +11,32 @@ Inactive="Neaktivan"
Start="Pokreni"
Stop="Zaustavi"
Captions="Natpisi (Eksperimentalno)"
Captions.AudioSource="Izvor zvuka"
Captions.CurrentSystemLanguage="Trenutni jezik sistema (%1)"
Captions.Provider="Provajder"
Captions.Error.GenericFail="Nemogućnost prikazivanja natpisa"
OutputTimer="Tempomat snimanja i emitovanja"
OutputTimer.Stream="Zaustavi emitovanje nakon:"
OutputTimer.Record="Zaustavi snimanje nakon:"
OutputTimer.Stream.StoppingIn="Prekidanje emitovanja za:"
OutputTimer.Record.StoppingIn="Prekidanje snimanja za:"
OutputTimer.Stream.EnableEverytime="Omogući štopovanje emitovanja svaki put"
OutputTimer.Record.EnableEverytime="Omogući štopovanje snimanja svaki put"
OutputTimer.Stream.EnableEverytime="Uključi tajmer strimovanja svaki put"
OutputTimer.Record.EnableEverytime="Uključi tajmer snimanja svaki put"
Scripts="Skripte"
LoadedScripts="Učitane skripte"
AddScripts="Dodaj skripte"
RemoveScripts="Izbaci skripte"
ReloadScripts="Ponovo učitaj skripte"
PythonSettings="Python podešavanja"
PythonSettings.PythonInstallPath32bit="Putanja do foldera sa Python instalacijom (32bit)"
PythonSettings.PythonInstallPath64bit="Putanja do foldera sa Python instalacijom (64bit)"
PythonSettings.BrowsePythonPath="Pretraži putanju do Python foldera"
ScriptLogWindow="Prijava skripte"
Description="Opis"
FileFilter.ScriptFiles="Fajlovi skripte"
FileFilter.AllFiles="Svi fajlovi"

View file

@ -11,14 +11,32 @@ Inactive="Неактиван"
Start="Покрени"
Stop="Заустави"
Captions="Натписи (експериментално)"
Captions.AudioSource="Извор звука"
Captions.CurrentSystemLanguage="Тренутни језик система (%1)"
Captions.Provider="Провајдер"
Captions.Error.GenericFail="Немогућност приказивања натписа"
OutputTimer="Темпомат снимања и емитовања"
OutputTimer.Stream="Заустави емитовање након:"
OutputTimer.Record="Заустави снимање након:"
OutputTimer.Stream.StoppingIn="Прекидање емитовања за:"
OutputTimer.Record.StoppingIn="Прекидање снимања за:"
OutputTimer.Stream.EnableEverytime="Омогући штоповање емитовање сваки пут"
OutputTimer.Record.EnableEverytime="Омогући штоповање снимања сваки пут"
OutputTimer.Stream.EnableEverytime="Укључи тајмер стримовања сваки пут"
OutputTimer.Record.EnableEverytime="Укључи тајмер снимања сваки пут"
Scripts="Скрипте"
LoadedScripts="Учитане скрипте"
AddScripts="Додај скрипте"
RemoveScripts="Избаци скрипте"
ReloadScripts="Поново учитај скрипте"
PythonSettings="Python подешавања"
PythonSettings.PythonInstallPath32bit="Путања до фолдера са Python инсталацијом (32bit)"
PythonSettings.PythonInstallPath64bit="Путања до фолдера са Python инсталацијом (64bit)"
PythonSettings.BrowsePythonPath="Претражи путању до Python фолдера"
ScriptLogWindow="Пријава скрипте"
Description="Опис"
FileFilter.ScriptFiles="Фајлови скрипте"
FileFilter.AllFiles="Сви фајлови"

View file

@ -0,0 +1,27 @@
SceneSwitcher="தானியங்கு காட்சி நிலைமாற்றி"
SceneSwitcher.OnNoMatch.DontSwitch="மாற வேண்டாம்"
SceneSwitcher.OnNoMatch.SwitchTo="மாற்று:"
SceneSwitcher.CheckInterval="செயலில் உள்ள சாளர தலைப்பை சரிபார்க்கவும்:"
SceneSwitcher.ActiveOrNotActive="காட்சி இடமாற்றி உள்ளது:"
InvalidRegex.Title="செல்லாத வழக்கமான வெளிப்பாடு"
InvalidRegex.Text="நீங்கள் உள்ளிட்ட வழக்கமான தொடர் தவறானது."
Active="செயலில்"
Inactive="செயலற்ற"
Start="தொடங்கு"
Stop="நிறுத்து"
Captions="தலைப்புகளை (சோதனை)"
Captions.AudioSource="ஒலி ஆதாரம்"
Captions.CurrentSystemLanguage="தற்போதைய அமைப்பு மொழி (%1)"
Captions.Provider="வழங்குநர்"
Captions.Error.GenericFail="தலைப்புகள் தொடங்குவதில் தோல்வி"
OutputTimer="வெளியீடு நேரம்"
OutputTimer.Stream="நேரலை நிறுத்த நேரம்:"
OutputTimer.Record="பதிவு நிறுத்த நேரம்:"
OutputTimer.Stream.StoppingIn="நேரலை முடிவடையும் நேரம்:"
OutputTimer.Record.StoppingIn="பதிவு முடிவடையும் நேரம்:"
Scripts="எழுத்து"

View file

@ -0,0 +1,13 @@
Active="ใช้งานอยู่"
Inactive="ไม่ใช้งาน"
Start="เริ่ม"
Stop="หยุด"
Scripts="สคริปต์"
AddScripts="เพิ่มสคริปต์"
Description="คำอธิบาย"
FileFilter.AllFiles="ไฟล์ทั้งหมด"

View file

@ -15,7 +15,7 @@ Captions="字幕 (实验)"
Captions.AudioSource="音频源"
Captions.CurrentSystemLanguage="当前系统语言 (%1)"
Captions.Provider="提供程序"
Captions.Error.GenericFail="启动捕获失败"
Captions.Error.GenericFail="字幕启动失败"
OutputTimer="输出计时器"
OutputTimer.Stream="停止流处理后:"

View file

@ -2,6 +2,7 @@ obs = obslua
source_name = ""
hotkey_id = obs.OBS_INVALID_HOTKEY_ID
attempts = 0
last_replay = ""
----------------------------------------------------------
@ -22,27 +23,45 @@ function try_play()
obs.obs_output_release(replay_buffer)
if path == last_replay then
path = nil
end
-- If the path is valid and the source exists, update it with the
-- replay file to play back the replay. Otherwise, stop attempting to
-- replay after 10 seconds
-- replay after 10 retries
if path == nil then
attempts = attempts + 1
if attempts >= 10 then
obs.remove_current_callback()
end
else
last_replay = path
local source = obs.obs_get_source_by_name(source_name)
if source ~= nil then
local settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "local_file", path)
obs.obs_data_set_bool(settings, "is_local_file", true)
obs.obs_data_set_bool(settings, "close_when_inactive", true)
obs.obs_data_set_bool(settings, "restart_on_activate", true)
source_id = obs.obs_source_get_id(source)
if source_id == "ffmpeg_source" then
obs.obs_data_set_string(settings, "local_file", path)
obs.obs_data_set_bool(settings, "is_local_file", true)
-- updating will automatically cause the source to
-- refresh if the source is currently active, otherwise
-- the source will play whenever its scene is activated
obs.obs_source_update(source, settings)
-- updating will automatically cause the source to
-- refresh if the source is currently active
obs.obs_source_update(source, settings)
elseif source_id == "vlc_source" then
-- "playlist"
array = obs.obs_data_array_create()
item = obs.obs_data_create()
obs.obs_data_set_string(item, "value", path)
obs.obs_data_array_push_back(array, item)
obs.obs_data_set_array(settings, "playlist", array)
-- updating will automatically cause the source to
-- refresh if the source is currently active
obs.obs_source_update(source, settings)
obs.obs_data_release(item)
obs.obs_data_array_release(array)
end
obs.obs_data_release(settings)
obs.obs_source_release(source)
@ -65,11 +84,11 @@ function instant_replay(pressed)
local ph = obs.obs_output_get_proc_handler(replay_buffer)
obs.proc_handler_call(ph, "save", nil)
-- Set a 1-second timer to attempt playback every 1 second
-- Set a 2-second timer to attempt playback every 1 second
-- until the replay is available
if obs.obs_output_active(replay_buffer) then
attempts = 0
obs.timer_add(try_play, 1000)
obs.timer_add(try_play, 2000)
else
obs.script_log(obs.LOG_WARNING, "Tried to save an instant replay, but the replay buffer is not active!")
end
@ -90,7 +109,7 @@ end
-- A function named script_description returns the description shown to
-- the user
function script_description()
return "When the \"Instant Replay\" hotkey is triggered, saves a replay with the replay buffer, and then plays it in a media source as soon as the replay is ready. Requires an active replay buffer.\n\nMade by Jim"
return "When the \"Instant Replay\" hotkey is triggered, saves a replay with the replay buffer, and then plays it in a media source as soon as the replay is ready. Requires an active replay buffer.\n\nMade by Jim and Exeldro"
end
-- A function named script_properties defines the properties that the user
@ -106,6 +125,11 @@ function script_properties()
if source_id == "ffmpeg_source" then
local name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)
elseif source_id == "vlc_source" then
local name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)
else
-- obs.script_log(obs.LOG_INFO, source_id)
end
end
end

View file

@ -18,6 +18,8 @@ OutputTimer::OutputTimer(QWidget *parent)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
QObject::connect(ui->outputTimerStream, SIGNAL(clicked()), this,
SLOT(StreamingTimerButton()));
QObject::connect(ui->outputTimerRecord, SIGNAL(clicked()), this,

View file

@ -230,6 +230,15 @@ void ScriptsTool::ReloadScript(const char *path)
const char *script_path = obs_script_get_path(script);
if (strcmp(script_path, path) == 0) {
obs_script_reload(script);
OBSData settings = obs_data_create();
obs_data_release(settings);
obs_properties_t *prop =
obs_script_get_properties(script);
obs_properties_apply_settings(prop, settings);
obs_properties_destroy(prop);
break;
}
}
@ -317,6 +326,14 @@ void ScriptsTool::on_addScripts_clicked()
QListWidgetItem *item = new QListWidgetItem(script_file);
item->setData(Qt::UserRole, QString(file));
ui->scripts->addItem(item);
OBSData settings = obs_data_create();
obs_data_release(settings);
obs_properties_t *prop =
obs_script_get_properties(script);
obs_properties_apply_settings(prop, settings);
obs_properties_destroy(prop);
}
}
}

View file

@ -1,3 +1,5 @@
#pragma once
#include <QWidget>
#include <QString>