System: Add capture file name format options

Include game-specific subdirectories.
pull/3730/head
Stenzek 5 months ago
parent fc9ce7fb2d
commit 4e963c1fb0
No known key found for this signature in database

@ -4374,6 +4374,13 @@ void FullscreenUI::DrawGraphicsSettingsPage()
DrawIntRangeSetting(bsi, FSUI_ICONVSTR(ICON_FA_CAMERA_RETRO, "Screenshot Quality"),
FSUI_VSTR("Selects the quality at which screenshots will be compressed."), "Display",
"ScreenshotQuality", Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY, 1, 100, "%d%%");
DrawEnumSetting(bsi, FSUI_ICONVSTR(ICON_FA_FILE, "Screenshot File Name Format"),
FSUI_VSTR("Determines the format of the screenshot file names."), "Display",
"ScreenshotFileNameFormat", Settings::DEFAULT_DISPLAY_SCREENSHOT_FILENAME_FORMAT,
&Settings::ParseCaptureFileNameFormat, &Settings::GetCaptureFileNameFormatName,
&Settings::GetCaptureFileNameFormatDisplayName, CaptureFileNameFormat::Count);
DrawFolderSetting(bsi, FSUI_ICONVSTR(ICON_FA_FOLDER, "Screenshot Directory"), "Folders", "Screenshots",
EmuFolders::Screenshots);
MenuHeading(FSUI_VSTR("Texture Replacements"));

@ -265,6 +265,7 @@ TRANSLATE_NOOP("FullscreenUI", "Determines that field that the game list will be
TRANSLATE_NOOP("FullscreenUI", "Determines the amount of audio buffered before being pulled by the host API.");
TRANSLATE_NOOP("FullscreenUI", "Determines the area of the overlay image that the display will be drawn within.");
TRANSLATE_NOOP("FullscreenUI", "Determines the emulated hardware type.");
TRANSLATE_NOOP("FullscreenUI", "Determines the format of the screenshot file names.");
TRANSLATE_NOOP("FullscreenUI", "Determines the format that screenshots will be saved/compressed with.");
TRANSLATE_NOOP("FullscreenUI", "Determines the frequency at which the macro will toggle the buttons on and off (aka auto fire).");
TRANSLATE_NOOP("FullscreenUI", "Determines the margin between the edge of the screen and on-screen messages.");
@ -675,6 +676,8 @@ TRANSLATE_NOOP("FullscreenUI", "Scanning Subdirectories");
TRANSLATE_NOOP("FullscreenUI", "Screen Margins");
TRANSLATE_NOOP("FullscreenUI", "Screen Position");
TRANSLATE_NOOP("FullscreenUI", "Screen Rotation");
TRANSLATE_NOOP("FullscreenUI", "Screenshot Directory");
TRANSLATE_NOOP("FullscreenUI", "Screenshot File Name Format");
TRANSLATE_NOOP("FullscreenUI", "Screenshot Format");
TRANSLATE_NOOP("FullscreenUI", "Screenshot Quality");
TRANSLATE_NOOP("FullscreenUI", "Screenshot Size");

@ -403,6 +403,11 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro
si.GetStringViewValue("Display", "ScreenshotFormat",
GetDisplayScreenshotFormatName(DEFAULT_DISPLAY_SCREENSHOT_FORMAT)))
.value_or(DEFAULT_DISPLAY_SCREENSHOT_FORMAT);
display_screenshot_filename_format =
ParseCaptureFileNameFormat(
si.GetStringViewValue("Display", "ScreenshotFileNameFormat",
GetCaptureFileNameFormatName(DEFAULT_DISPLAY_SCREENSHOT_FILENAME_FORMAT)))
.value_or(DEFAULT_DISPLAY_SCREENSHOT_FILENAME_FORMAT);
display_screenshot_quality = static_cast<u8>(
std::clamp<u32>(si.GetUIntValue("Display", "ScreenshotQuality", DEFAULT_DISPLAY_SCREENSHOT_QUALITY), 1, 100));
display_optimal_frame_pacing = si.GetBoolValue("Display", "OptimalFramePacing", DEFAULT_OPTIMAL_FRAME_PACING);
@ -772,6 +777,8 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
GetDisplayExclusiveFullscreenControlName(display_exclusive_fullscreen_control));
si.SetStringValue("Display", "ScreenshotMode", GetDisplayScreenshotModeName(display_screenshot_mode));
si.SetStringValue("Display", "ScreenshotFormat", GetDisplayScreenshotFormatName(display_screenshot_format));
si.SetStringValue("Display", "ScreenshotFileNameFormat",
GetCaptureFileNameFormatName(display_screenshot_filename_format));
si.SetUIntValue("Display", "ScreenshotQuality", display_screenshot_quality);
if (!ignore_base)
{
@ -2358,6 +2365,46 @@ std::optional<DisplayScreenshotFormat> Settings::GetDisplayScreenshotFormatFromF
return std::nullopt;
}
static constexpr const std::array s_capture_file_name_format_names = {
"Timestamp",
"TitleAndTimestamp",
"TimestampInFolder",
"TitleAndTimestampInFolder",
};
static_assert(s_capture_file_name_format_names.size() == static_cast<size_t>(CaptureFileNameFormat::Count));
static constexpr const std::array s_capture_file_name_format_display_names = {
TRANSLATE_DISAMBIG_NOOP("Settings", "Timestamp", "CaptureFileNameFormat"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Game and Timestamp", "CaptureFileNameFormat"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Timestamp in Game Folder", "CaptureFileNameFormat"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Game and Timestamp in Game Folder", "CaptureFileNameFormat"),
};
static_assert(s_capture_file_name_format_names.size() == static_cast<size_t>(CaptureFileNameFormat::Count));
std::optional<CaptureFileNameFormat> Settings::ParseCaptureFileNameFormat(std::string_view str)
{
int index = 0;
for (const char* name : s_capture_file_name_format_names)
{
if (str == name)
return static_cast<CaptureFileNameFormat>(index);
index++;
}
return std::nullopt;
}
const char* Settings::GetCaptureFileNameFormatName(CaptureFileNameFormat format)
{
return s_capture_file_name_format_names[static_cast<size_t>(format)];
}
const char* Settings::GetCaptureFileNameFormatDisplayName(CaptureFileNameFormat format)
{
return Host::TranslateToCString("Settings", s_capture_file_name_format_display_names[static_cast<size_t>(format)],
"CaptureFileNameFormat");
}
static constexpr const std::array s_display_osd_message_type_names = {
"Error", "Warning", "Info", "Quick", "Persistent",
};

@ -51,8 +51,6 @@ struct GPUSettings
DisplayScalingMode display_scaling_24bit = DEFAULT_DISPLAY_SCALING;
DisplayExclusiveFullscreenControl display_exclusive_fullscreen_control = DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL;
DisplayScreenshotMode display_screenshot_mode = DEFAULT_DISPLAY_SCREENSHOT_MODE;
DisplayScreenshotFormat display_screenshot_format = DEFAULT_DISPLAY_SCREENSHOT_FORMAT;
u8 display_screenshot_quality = DEFAULT_DISPLAY_SCREENSHOT_QUALITY;
u8 gpu_max_queued_frames = DEFAULT_GPU_MAX_QUEUED_FRAMES;
s16 display_active_start_offset = 0;
s16 display_active_end_offset = 0;
@ -241,8 +239,6 @@ struct GPUSettings
static constexpr DisplayExclusiveFullscreenControl DEFAULT_DISPLAY_EXCLUSIVE_FULLSCREEN_CONTROL =
DisplayExclusiveFullscreenControl::Automatic;
static constexpr DisplayScreenshotMode DEFAULT_DISPLAY_SCREENSHOT_MODE = DisplayScreenshotMode::ScreenResolution;
static constexpr DisplayScreenshotFormat DEFAULT_DISPLAY_SCREENSHOT_FORMAT = DisplayScreenshotFormat::PNG;
static constexpr u8 DEFAULT_DISPLAY_SCREENSHOT_QUALITY = 85;
static constexpr float DEFAULT_DISPLAY_PRE_FRAME_SLEEP_BUFFER = 2.0f;
static constexpr float DEFAULT_OSD_SCALE = 100.0f;
static constexpr NotificationLocation DEFAULT_OSD_MESSAGE_LOCATION = NotificationLocation::TopLeft;
@ -342,6 +338,10 @@ struct Settings : public GPUSettings
u32 cdrom_max_seek_speedup_cycles = DEFAULT_CDROM_MAX_SEEK_SPEEDUP_CYCLES;
u32 cdrom_max_read_speedup_cycles = DEFAULT_CDROM_MAX_READ_SPEEDUP_CYCLES;
DisplayScreenshotFormat display_screenshot_format = DEFAULT_DISPLAY_SCREENSHOT_FORMAT;
u8 display_screenshot_quality = DEFAULT_DISPLAY_SCREENSHOT_QUALITY;
CaptureFileNameFormat display_screenshot_filename_format = DEFAULT_DISPLAY_SCREENSHOT_FILENAME_FORMAT;
u8 audio_output_volume = 100;
u8 audio_fast_forward_volume = 100;
@ -585,6 +585,10 @@ struct Settings : public GPUSettings
static const char* GetDisplayScreenshotFormatExtension(DisplayScreenshotFormat mode);
static std::optional<DisplayScreenshotFormat> GetDisplayScreenshotFormatFromFileName(const std::string_view filename);
static std::optional<CaptureFileNameFormat> ParseCaptureFileNameFormat(std::string_view str);
static const char* GetCaptureFileNameFormatName(CaptureFileNameFormat format);
static const char* GetCaptureFileNameFormatDisplayName(CaptureFileNameFormat format);
static const char* GetDisplayOSDMessageTypeName(OSDMessageType type);
static std::optional<MemoryCardType> ParseMemoryCardTypeName(std::string_view str);
@ -631,6 +635,11 @@ struct Settings : public GPUSettings
static constexpr u32 DEFAULT_CDROM_MAX_READ_SPEEDUP_CYCLES = 30000;
static constexpr CDROMMechaconVersion DEFAULT_CDROM_MECHACON_VERSION = CDROMMechaconVersion::VC1A;
static constexpr DisplayScreenshotFormat DEFAULT_DISPLAY_SCREENSHOT_FORMAT = DisplayScreenshotFormat::PNG;
static constexpr u8 DEFAULT_DISPLAY_SCREENSHOT_QUALITY = 85;
static constexpr CaptureFileNameFormat DEFAULT_DISPLAY_SCREENSHOT_FILENAME_FORMAT =
CaptureFileNameFormat::TitleAndTimestamp;
static constexpr ControllerType DEFAULT_CONTROLLER_1_TYPE = ControllerType::AnalogController;
static constexpr ControllerType DEFAULT_CONTROLLER_2_TYPE = ControllerType::None;
static constexpr MemoryCardType DEFAULT_MEMORY_CARD_1_TYPE = MemoryCardType::PerGameTitle;
@ -649,6 +658,8 @@ struct Settings : public GPUSettings
static constexpr u32 DEFAULT_MEDIA_CAPTURE_VIDEO_HEIGHT = 480;
static constexpr u32 DEFAULT_MEDIA_CAPTURE_VIDEO_BITRATE = 6000;
static constexpr u32 DEFAULT_MEDIA_CAPTURE_AUDIO_BITRATE = 128;
static constexpr CaptureFileNameFormat DEFAULT_MEDIA_CAPTURE_FILENAME_FORMAT =
CaptureFileNameFormat::TitleAndTimestamp;
// Android doesn't create settings until they're first opened, so we have to override the defaults here.
#ifndef __ANDROID__

@ -181,7 +181,6 @@ static void ClearRunningGame();
static void DestroySystem();
static void RecreateGPU(GPURenderer new_renderer);
static std::string GetScreenshotPath(std::string_view extension);
static bool StartMediaCapture(std::string path, bool capture_video, bool capture_audio, u32 video_width,
u32 video_height);
static void StopMediaCapture(std::unique_ptr<MediaCapture> cap);
@ -357,11 +356,6 @@ static StateVars s_state;
} // namespace System
static TinyString GetTimestampStringForFileName()
{
return TinyString::from_format("{:%Y-%m-%d-%H-%M-%S}", Common::LocalTime(std::time(nullptr)).value_or(std::tm{}));
}
bool System::PerformEarlyHardwareChecks(Error* error)
{
// This shouldn't fail... if it does, just hope for the best.
@ -1428,6 +1422,8 @@ void System::SetDefaultSettings(SettingsInterface& si)
#ifndef __ANDROID__
si.SetStringValue("MediaCapture", "Backend", MediaCapture::GetBackendName(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND));
si.SetStringValue("MediaCapture", "Container", Settings::DEFAULT_MEDIA_CAPTURE_CONTAINER);
si.SetStringValue("MediaCapture", "FileNameFormat",
Settings::GetCaptureFileNameFormatName(Settings::DEFAULT_MEDIA_CAPTURE_FILENAME_FORMAT));
si.SetBoolValue("MediaCapture", "VideoCapture", true);
si.SetUIntValue("MediaCapture", "VideoWidth", Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_WIDTH);
si.SetUIntValue("MediaCapture", "VideoHeight", Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_HEIGHT);
@ -4836,8 +4832,6 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
g_settings.display_show_enhancements != old_settings.display_show_enhancements ||
g_settings.display_auto_resize_window != old_settings.display_auto_resize_window ||
g_settings.display_screenshot_mode != old_settings.display_screenshot_mode ||
g_settings.display_screenshot_format != old_settings.display_screenshot_format ||
g_settings.display_screenshot_quality != old_settings.display_screenshot_quality ||
g_settings.display_osd_scale != old_settings.display_osd_scale ||
g_settings.display_osd_margin != old_settings.display_osd_margin ||
g_settings.display_osd_message_duration != old_settings.display_osd_message_duration ||
@ -5624,29 +5618,84 @@ void System::UpdateVolume()
SPU::GetOutputStream().SetOutputVolume(GetAudioOutputVolume());
}
std::string System::GetScreenshotPath(std::string_view extension)
std::string System::GetNewCapturePath(const std::string& directory, const std::string_view title,
CaptureFileNameFormat format, std::string_view extension)
{
const std::string sanitized_name = Path::SanitizeFileName(System::GetGameTitle());
std::string basename;
if (sanitized_name.empty())
basename = fmt::format("{}", GetTimestampStringForFileName());
// don't calculate if unnecessary
std::string sanitized_title;
if (!title.empty() &&
(format == CaptureFileNameFormat::TitleAndTimestamp || format >= CaptureFileNameFormat::TimestampInFolder))
{
sanitized_title = Path::SanitizeFileName(title);
}
std::string path;
if (format >= CaptureFileNameFormat::TimestampInFolder && !sanitized_title.empty())
{
path = Path::Combine(directory, sanitized_title);
if (Error error; !FileSystem::EnsureDirectoryExists(path.c_str(), false, &error)) [[unlikely]]
{
WARNING_LOG("Failed to create capture subdirectory '{}': {}", path, error.GetDescription());
path = directory;
}
}
else
basename = fmt::format("{} {}", sanitized_name, GetTimestampStringForFileName());
{
path = directory;
}
path += FS_OSPATH_SEPARATOR_CHARACTER;
if ((format == CaptureFileNameFormat::TitleAndTimestamp ||
format == CaptureFileNameFormat::TitleAndTimestampInFolder) &&
!sanitized_title.empty())
{
path += sanitized_title;
path += ' ';
}
std::string path = fmt::format("{}" FS_OSPATH_SEPARATOR_STR "{}.{}", EmuFolders::Screenshots, basename, extension);
fmt::format_to(std::back_inserter(path), "{:%Y-%m-%d-%H-%M-%S}",
Common::LocalTime(std::time(nullptr)).value_or(std::tm{}));
if (!extension.empty())
{
path += '.';
path += extension;
}
// handle quick screenshots to the same filename
u32 next_suffix = 1;
while (FileSystem::FileExists(path.c_str()))
{
path =
fmt::format("{}" FS_OSPATH_SEPARATOR_STR "{} ({}).{}", EmuFolders::Screenshots, basename, next_suffix, extension);
// remove and re-add the extension
if (!extension.empty())
path.erase(path.rfind('.'));
// and the suffix if this isn't the first
if (next_suffix > 1)
path.erase(path.rfind(' '));
if (!extension.empty())
fmt::format_to(std::back_inserter(path), " ({}).{}", next_suffix, extension);
else
fmt::format_to(std::back_inserter(path), " ({})", next_suffix);
next_suffix++;
}
return path;
}
std::string System::GetNewMediaCapturePath(const std::string_view title, const std::string_view container)
{
const CaptureFileNameFormat format =
Settings::ParseCaptureFileNameFormat(Core::GetBaseTinyStringSettingValue("MediaCapture", "FilenameFormat"))
.value_or(Settings::DEFAULT_MEDIA_CAPTURE_FILENAME_FORMAT);
return GetNewCapturePath(EmuFolders::Videos, title, format, container);
}
void System::SaveScreenshot(const char* path, DisplayScreenshotMode mode, DisplayScreenshotFormat format, u8 quality)
{
if (!IsValid())
@ -5654,7 +5703,12 @@ void System::SaveScreenshot(const char* path, DisplayScreenshotMode mode, Displa
std::string auto_path;
if (!path || path[0] == '\0')
path = (auto_path = GetScreenshotPath(Settings::GetDisplayScreenshotFormatExtension(format))).c_str();
{
path = (auto_path = GetNewCapturePath(EmuFolders::Screenshots, s_state.running_game_title,
g_settings.display_screenshot_filename_format,
Settings::GetDisplayScreenshotFormatExtension(format)))
.c_str();
}
GPUBackend::RenderScreenshotToFile(path, mode, quality, true);
}
@ -5666,7 +5720,11 @@ bool System::StartRecordingGPUDump(const char* path /*= nullptr*/, u32 num_frame
std::string auto_path;
if (!path)
path = (auto_path = GetScreenshotPath("psxgpu")).c_str();
{
path = (auto_path = GetNewCapturePath(EmuFolders::Screenshots, s_state.running_game_title,
g_settings.display_screenshot_filename_format, "psxgpu"))
.c_str();
}
return g_gpu.StartRecordingGPUDump(path, num_frames);
}
@ -5691,23 +5749,6 @@ MediaCapture* System::GetMediaCapture()
return s_state.media_capture.get();
}
std::string System::GetNewMediaCapturePath(const std::string_view title, const std::string_view container)
{
const std::string sanitized_name = Path::SanitizeFileName(title);
std::string path;
if (sanitized_name.empty())
{
path = Path::Combine(EmuFolders::Videos, fmt::format("{}.{}", GetTimestampStringForFileName(), container));
}
else
{
path = Path::Combine(EmuFolders::Videos,
fmt::format("{} {}.{}", sanitized_name, GetTimestampStringForFileName(), container));
}
return path;
}
bool System::StartMediaCapture(std::string path)
{
const bool capture_video = Core::GetBoolSettingValue("MediaCapture", "VideoCapture", true);
@ -5764,9 +5805,9 @@ bool System::StartMediaCapture(std::string path, bool capture_video, bool captur
if (path.empty())
{
path =
GetNewMediaCapturePath(GetGameTitle(), Core::GetStringSettingValue("MediaCapture", "Container",
Settings::DEFAULT_MEDIA_CAPTURE_CONTAINER));
path = GetNewMediaCapturePath(
s_state.running_game_title,
Core::GetTinyStringSettingValue("MediaCapture", "Container", Settings::DEFAULT_MEDIA_CAPTURE_CONTAINER));
}
const MediaCaptureBackend backend =

@ -427,6 +427,8 @@ bool StartRecordingGPUDump(const char* path = nullptr, u32 num_frames = 1);
void StopRecordingGPUDump();
/// Returns the path that a new media capture would be saved to by default. Safe to call from any thread.
std::string GetNewCapturePath(const std::string& directory, const std::string_view title, CaptureFileNameFormat format,
std::string_view extension);
std::string GetNewMediaCapturePath(const std::string_view title, const std::string_view container);
/// Current media capture (if active).

@ -226,6 +226,15 @@ enum class DisplayScreenshotFormat : u8
Count
};
enum class CaptureFileNameFormat : u8
{
Timestamp,
TitleAndTimestamp,
TimestampInFolder,
TitleAndTimestampInFolder,
Count
};
enum class PresentSkipMode : u8
{
Disabled,

@ -33,6 +33,10 @@ CaptureSettingsWidget::CaptureSettingsWidget(SettingsWindow* dialog, QWidget* pa
tr("Select Screenshots Directory"), m_ui.screenshotsDirectoryOpen,
m_ui.screenshotsDirectoryReset, "Folders", "Screenshots",
Path::Combine(EmuFolders::DataRoot, "screenshots"));
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.screenshotSaveName, "Display", "ScreenshotFileNameFormat", &Settings::ParseCaptureFileNameFormat,
&Settings::GetCaptureFileNameFormatName, &Settings::GetCaptureFileNameFormatDisplayName,
Settings::DEFAULT_DISPLAY_SCREENSHOT_FILENAME_FORMAT, CaptureFileNameFormat::Count);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.mediaCaptureBackend, "MediaCapture", "Backend",
&MediaCapture::ParseBackendName, &MediaCapture::GetBackendName,
@ -42,6 +46,10 @@ CaptureSettingsWidget::CaptureSettingsWidget(SettingsWindow* dialog, QWidget* pa
tr("Select Media Capture Directory"), m_ui.videosDirectoryOpen,
m_ui.videosDirectoryReset, "Folders", "Videos",
Path::Combine(EmuFolders::DataRoot, "videos"));
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.mediaCaptureSaveName, "MediaCapture", "FilenameFormat", &Settings::ParseCaptureFileNameFormat,
&Settings::GetCaptureFileNameFormatName, &Settings::GetCaptureFileNameFormatDisplayName,
Settings::DEFAULT_DISPLAY_SCREENSHOT_FILENAME_FORMAT, CaptureFileNameFormat::Count);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCapture, "MediaCapture", "VideoCapture", true);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureWidth, "MediaCapture", "VideoWidth",
Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_WIDTH);
@ -80,6 +88,11 @@ CaptureSettingsWidget::CaptureSettingsWidget(SettingsWindow* dialog, QWidget* pa
"preserve more detail at the cost of file size."));
dialog->registerWidgetHelp(m_ui.screenshotsDirectory, tr("Save Location"), tr("Default"),
tr("Specifies the directory where screenshots will be saved."));
dialog->registerWidgetHelp(
m_ui.screenshotSaveName, tr("Save Name"),
Settings::GetCaptureFileNameFormatDisplayName(Settings::DEFAULT_DISPLAY_SCREENSHOT_FILENAME_FORMAT),
tr("Determines the format of the filename used when saving screenshots, and whether a subdirectory is created "
"per-game."));
dialog->registerWidgetHelp(
m_ui.screenshotFormat, tr("Screenshot Format"), tr("PNG"),
tr("Selects the format which will be used to save screenshots. JPEG produces smaller files, but loses detail."));
@ -95,6 +108,11 @@ CaptureSettingsWidget::CaptureSettingsWidget(SettingsWindow* dialog, QWidget* pa
tr("Determines the file format used to contain the captured audio/video."));
dialog->registerWidgetHelp(m_ui.videosDirectory, tr("Save Location"), tr("Default"),
tr("Specifies the directory where media capture (video/audio) will be saved."));
dialog->registerWidgetHelp(
m_ui.mediaCaptureSaveName, tr("Save Name"),
Settings::GetCaptureFileNameFormatDisplayName(Settings::DEFAULT_MEDIA_CAPTURE_FILENAME_FORMAT),
tr("Determines the format of the filename used when saving screenshots, and whether a subdirectory is created "
"per-game."));
dialog->registerWidgetHelp(m_ui.enableVideoCapture, tr("Capture Video"), tr("Checked"),
tr("Captures video to the chosen file when media capture is started. If unchecked, the "
"file will only contain audio."));

@ -70,13 +70,23 @@
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="screenshotNameLabel">
<property name="text">
<string>Save Name:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="screenshotSaveName"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="screenshotsDirectoryLabel">
<property name="text">
<string>Save Location:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<layout class="QHBoxLayout" name="screenshotsDirectoryLayout">
<item>
<widget class="QLineEdit" name="screenshotsDirectory"/>
@ -143,13 +153,23 @@
<widget class="QComboBox" name="captureContainer"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mediaCaptureSaveNameLabel">
<property name="text">
<string>Save Name:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="mediaCaptureSaveName"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="videosDirectoryLabel">
<property name="text">
<string>Save Location:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<layout class="QHBoxLayout" name="videosDirectoryLayout">
<item>
<widget class="QLineEdit" name="videosDirectory"/>
@ -186,7 +206,7 @@
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<layout class="QGridLayout" name="captureOptionLayout">
<property name="horizontalSpacing">
<number>20</number>

Loading…
Cancel
Save