mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-03-31 09:07:13 +09:00
Add -ffmpeg-video-opts and -ffmpeg-audio-opts
This commit is contained in:
4
TODO
4
TODO
@@ -387,3 +387,7 @@ Support camera controls, such as white balance. Otherwise tell user to use camer
|
|||||||
Camera capture doesn't work perfectly. The image gets glitched, need to properly wait for image to be done.
|
Camera capture doesn't work perfectly. The image gets glitched, need to properly wait for image to be done.
|
||||||
|
|
||||||
Use one pipewire connection (pipewire video) instead of multiple ones when recording with portal multiple times (multiple sources).
|
Use one pipewire connection (pipewire video) instead of multiple ones when recording with portal multiple times (multiple sources).
|
||||||
|
|
||||||
|
Close pipewire links or maybe there are file descriptor leaks?
|
||||||
|
|
||||||
|
Make multiple capture sources work properly in regards to size. The size of the video should be the region size of each capture source.
|
||||||
@@ -302,9 +302,25 @@ Script to run after saving video. Receives filepath and type ("regular", "replay
|
|||||||
Portal session token file (default: ~/.config/gpu-screen-recorder/restore_token).
|
Portal session token file (default: ~/.config/gpu-screen-recorder/restore_token).
|
||||||
.TP
|
.TP
|
||||||
.BI \-ffmpeg-opts " options"
|
.BI \-ffmpeg-opts " options"
|
||||||
Additional arguments to pass to FFmpeg in a list of key-values pairs in the format "key=value;key=value",
|
Additional arguments to pass to FFmpeg for the file in a list of key-values pairs in the format "key=value;key=value",
|
||||||
.br
|
.br
|
||||||
for example: -ffmpeg-opts "hls_list_size=3;hls_time=1;hls_flags=delete_segments".
|
for example: -ffmpeg-opts "hls_list_size=3;hls_time=1;hls_flags=delete_segments".
|
||||||
|
.br
|
||||||
|
Note: this overwrites options set by GPU Screen Recorder with the same name.
|
||||||
|
.TP
|
||||||
|
.BI \-ffmpeg-video-opts " options"
|
||||||
|
Additional arguments to pass to FFmpeg for the video in a list of key-values pairs in the format "key=value;key=value",
|
||||||
|
.br
|
||||||
|
for example: -ffmpeg-video-opts "codec=cabac;rc_mode=CQP;qp=16".
|
||||||
|
.br
|
||||||
|
Note: this overwrites options set by GPU Screen Recorder with the same name.
|
||||||
|
.TP
|
||||||
|
.BI \-ffmpeg-audio-opts " options"
|
||||||
|
Additional arguments to pass to FFmpeg for the audio in a list of key-values pairs in the format "key=value;key=value",
|
||||||
|
.br
|
||||||
|
for example: -ffmpeg-audio-opts "aac_coder=fast;aac_pce=true".
|
||||||
|
.br
|
||||||
|
Note: this overwrites options set by GPU Screen Recorder with the same name.
|
||||||
.TP
|
.TP
|
||||||
.BI \-gl\-debug " yes|no"
|
.BI \-gl\-debug " yes|no"
|
||||||
OpenGL debug output (default: no).
|
OpenGL debug output (default: no).
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
typedef struct gsr_egl gsr_egl;
|
typedef struct gsr_egl gsr_egl;
|
||||||
|
|
||||||
#define NUM_ARGS 33
|
#define NUM_ARGS 35
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GSR_CAPTURE_SOURCE_TYPE_WINDOW,
|
GSR_CAPTURE_SOURCE_TYPE_WINDOW,
|
||||||
@@ -86,6 +86,8 @@ typedef struct {
|
|||||||
const char *portal_session_token_filepath;
|
const char *portal_session_token_filepath;
|
||||||
const char *recording_saved_script;
|
const char *recording_saved_script;
|
||||||
const char *ffmpeg_opts;
|
const char *ffmpeg_opts;
|
||||||
|
const char *ffmpeg_video_opts;
|
||||||
|
const char *ffmpeg_audio_opts;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool gl_debug;
|
bool gl_debug;
|
||||||
bool fallback_cpu_encoding;
|
bool fallback_cpu_encoding;
|
||||||
|
|||||||
@@ -441,6 +441,8 @@ static bool args_parser_set_values(args_parser *self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self->ffmpeg_opts = args_get_value_by_key(self->args, NUM_ARGS, "-ffmpeg-opts");
|
self->ffmpeg_opts = args_get_value_by_key(self->args, NUM_ARGS, "-ffmpeg-opts");
|
||||||
|
self->ffmpeg_video_opts = args_get_value_by_key(self->args, NUM_ARGS, "-ffmpeg-video-opts");
|
||||||
|
self->ffmpeg_audio_opts = args_get_value_by_key(self->args, NUM_ARGS, "-ffmpeg-audio-opts");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -532,6 +534,8 @@ bool args_parser_parse(args_parser *self, int argc, char **argv, const args_hand
|
|||||||
self->args[arg_index++] = (Arg){ .key = "-replay-storage", .optional = true, .list = false, .type = ARG_TYPE_ENUM, .enum_values = replay_storage_enums, .num_enum_values = sizeof(replay_storage_enums)/sizeof(ArgEnum) };
|
self->args[arg_index++] = (Arg){ .key = "-replay-storage", .optional = true, .list = false, .type = ARG_TYPE_ENUM, .enum_values = replay_storage_enums, .num_enum_values = sizeof(replay_storage_enums)/sizeof(ArgEnum) };
|
||||||
self->args[arg_index++] = (Arg){ .key = "-p", .optional = true, .list = true, .type = ARG_TYPE_STRING };
|
self->args[arg_index++] = (Arg){ .key = "-p", .optional = true, .list = true, .type = ARG_TYPE_STRING };
|
||||||
self->args[arg_index++] = (Arg){ .key = "-ffmpeg-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING };
|
self->args[arg_index++] = (Arg){ .key = "-ffmpeg-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING };
|
||||||
|
self->args[arg_index++] = (Arg){ .key = "-ffmpeg-video-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING };
|
||||||
|
self->args[arg_index++] = (Arg){ .key = "-ffmpeg-audio-opts", .optional = true, .list = false, .type = ARG_TYPE_STRING };
|
||||||
assert(arg_index == NUM_ARGS);
|
assert(arg_index == NUM_ARGS);
|
||||||
|
|
||||||
for(int i = 1; i < argc; i += 2) {
|
for(int i = 1; i < argc; i += 2) {
|
||||||
|
|||||||
16
src/main.cpp
16
src/main.cpp
@@ -528,10 +528,13 @@ static AVCodecContext *create_video_codec_context(AVPixelFormat pix_fmt, const A
|
|||||||
return codec_context;
|
return codec_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void open_audio(AVCodecContext *audio_codec_context) {
|
static void open_audio(AVCodecContext *audio_codec_context, const char *ffmpeg_audio_opts) {
|
||||||
AVDictionary *options = nullptr;
|
AVDictionary *options = nullptr;
|
||||||
av_dict_set(&options, "strict", "experimental", 0);
|
av_dict_set(&options, "strict", "experimental", 0);
|
||||||
|
|
||||||
|
if(ffmpeg_audio_opts)
|
||||||
|
av_dict_parse_string(&options, ffmpeg_audio_opts, "=", ";", 0);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
ret = avcodec_open2(audio_codec_context, audio_codec_context->codec, &options);
|
ret = avcodec_open2(audio_codec_context, audio_codec_context->codec, &options);
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
@@ -678,6 +681,9 @@ static void open_video_software(AVCodecContext *codec_context, const args_parser
|
|||||||
|
|
||||||
av_dict_set(&options, "strict", "experimental", 0);
|
av_dict_set(&options, "strict", "experimental", 0);
|
||||||
|
|
||||||
|
if(arg_parser.ffmpeg_video_opts)
|
||||||
|
av_dict_parse_string(&options, arg_parser.ffmpeg_video_opts, "=", ";", 0);
|
||||||
|
|
||||||
int ret = avcodec_open2(codec_context, codec_context->codec, &options);
|
int ret = avcodec_open2(codec_context, codec_context->codec, &options);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "gsr error: Could not open video codec: %s\n", av_error_to_string(ret));
|
fprintf(stderr, "gsr error: Could not open video codec: %s\n", av_error_to_string(ret));
|
||||||
@@ -926,6 +932,9 @@ static void open_video_hardware(AVCodecContext *codec_context, bool low_power, c
|
|||||||
|
|
||||||
av_dict_set(&options, "strict", "experimental", 0);
|
av_dict_set(&options, "strict", "experimental", 0);
|
||||||
|
|
||||||
|
if(arg_parser.ffmpeg_video_opts)
|
||||||
|
av_dict_parse_string(&options, arg_parser.ffmpeg_video_opts, "=", ";", 0);
|
||||||
|
|
||||||
int ret = avcodec_open2(codec_context, codec_context->codec, &options);
|
int ret = avcodec_open2(codec_context, codec_context->codec, &options);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "gsr error: Could not open video codec: %s\n", av_error_to_string(ret));
|
fprintf(stderr, "gsr error: Could not open video codec: %s\n", av_error_to_string(ret));
|
||||||
@@ -1219,6 +1228,7 @@ static RecordingStartResult start_recording_create_streams(const char *filename,
|
|||||||
|
|
||||||
AVDictionary *options = nullptr;
|
AVDictionary *options = nullptr;
|
||||||
av_dict_set(&options, "strict", "experimental", 0);
|
av_dict_set(&options, "strict", "experimental", 0);
|
||||||
|
|
||||||
if(args_parser.ffmpeg_opts)
|
if(args_parser.ffmpeg_opts)
|
||||||
av_dict_parse_string(&options, args_parser.ffmpeg_opts, "=", ";", 0);
|
av_dict_parse_string(&options, args_parser.ffmpeg_opts, "=", ";", 0);
|
||||||
|
|
||||||
@@ -2388,6 +2398,7 @@ static std::vector<VideoSource> create_video_sources(const args_parser &arg_pars
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Video size should be end pos - start pos, where start pos = pos and end pos = pos + size
|
||||||
video_size = {0, 0};
|
video_size = {0, 0};
|
||||||
for(const VideoSource &video_source : video_sources) {
|
for(const VideoSource &video_source : video_sources) {
|
||||||
video_size.x = std::max(video_size.x, video_source.metadata.video_size.x);
|
video_size.x = std::max(video_size.x, video_source.metadata.video_size.x);
|
||||||
@@ -3441,6 +3452,7 @@ static bool av_open_file_write_header(AVFormatContext *av_format_context, const
|
|||||||
|
|
||||||
AVDictionary *options = nullptr;
|
AVDictionary *options = nullptr;
|
||||||
av_dict_set(&options, "strict", "experimental", 0);
|
av_dict_set(&options, "strict", "experimental", 0);
|
||||||
|
|
||||||
if(ffmpeg_opts)
|
if(ffmpeg_opts)
|
||||||
av_dict_parse_string(&options, ffmpeg_opts, "=", ";", 0);
|
av_dict_parse_string(&options, ffmpeg_opts, "=", ";", 0);
|
||||||
|
|
||||||
@@ -3934,7 +3946,7 @@ int main(int argc, char **argv) {
|
|||||||
if(audio_stream && !merged_audio_inputs.track_name.empty())
|
if(audio_stream && !merged_audio_inputs.track_name.empty())
|
||||||
av_dict_set(&audio_stream->metadata, "title", merged_audio_inputs.track_name.c_str(), 0);
|
av_dict_set(&audio_stream->metadata, "title", merged_audio_inputs.track_name.c_str(), 0);
|
||||||
|
|
||||||
open_audio(audio_codec_context);
|
open_audio(audio_codec_context, arg_parser.ffmpeg_audio_opts);
|
||||||
if(audio_stream)
|
if(audio_stream)
|
||||||
avcodec_parameters_from_context(audio_stream->codecpar, audio_codec_context);
|
avcodec_parameters_from_context(audio_stream->codecpar, audio_codec_context);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user