Add pulseaudio, parse command line args
This commit is contained in:
parent
2fcd3ee3e5
commit
32b66c95ff
@ -24,6 +24,4 @@ void sound_device_close(SoundDevice *device);
|
|||||||
*/
|
*/
|
||||||
int sound_device_read_next_chunk(SoundDevice *device, void **buffer);
|
int sound_device_read_next_chunk(SoundDevice *device, void **buffer);
|
||||||
|
|
||||||
int sound_device_get_buffer_size(SoundDevice *device);
|
|
||||||
|
|
||||||
#endif /* GPU_SCREEN_RECORDER_H */
|
#endif /* GPU_SCREEN_RECORDER_H */
|
||||||
|
3
list-sinks.sh
Executable file
3
list-sinks.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
pactl list | grep -E '(Description: Monitor of)|(Monitor Source: )'
|
@ -8,6 +8,9 @@ platforms = ["posix"]
|
|||||||
include_dirs = ["/opt/cuda/targets/x86_64-linux/include"]
|
include_dirs = ["/opt/cuda/targets/x86_64-linux/include"]
|
||||||
libs = ["/usr/lib/libcuda.so"]
|
libs = ["/usr/lib/libcuda.so"]
|
||||||
|
|
||||||
|
[define]
|
||||||
|
PULSEAUDIO = "1"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glew = ">=2"
|
glew = ">=2"
|
||||||
glx = ">=1"
|
glx = ">=1"
|
||||||
@ -22,5 +25,6 @@ xdamage = "1"
|
|||||||
glfw3 = "3"
|
glfw3 = "3"
|
||||||
|
|
||||||
alsa = "1"
|
alsa = "1"
|
||||||
|
libpulse-simple = "13"
|
||||||
|
|
||||||
libswresample = "3"
|
libswresample = "3"
|
48
src/main.cpp
48
src/main.cpp
@ -5,6 +5,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -503,17 +504,46 @@ static void close_video(AVStream *video_stream, AVFrame *frame) {
|
|||||||
// av_frame_free(&frame);
|
// av_frame_free(&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usage() {
|
||||||
|
fprintf(stderr, "usage: gpu-screen-recorder -w <window_id> -c <container_format> -f <fps> -a <audio_input>\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
if (argc < 4) {
|
std::map<std::string, std::string> args = {
|
||||||
fprintf(stderr, "usage: gpu-screen-recorder <window_id> <container_format> <fps>\n");
|
{ "-w", "" },
|
||||||
return 1;
|
{ "-c", "" },
|
||||||
|
{ "-f", "" },
|
||||||
|
{ "-a", "" },
|
||||||
|
};
|
||||||
|
|
||||||
|
for(int i = 1; i < argc; i += 2) {
|
||||||
|
bool valid_arg = false;
|
||||||
|
for(auto &it : args) {
|
||||||
|
if(strcmp(argv[i], it.first.c_str()) == 0) {
|
||||||
|
it.second = argv[i + 1];
|
||||||
|
valid_arg = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!valid_arg) {
|
||||||
|
fprintf(stderr, "Invalid argument '%s'\n", argv[i]);
|
||||||
|
usage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Window src_window_id = strtol(argv[1], nullptr, 0);
|
for(auto &it : args) {
|
||||||
const char *container_format = argv[2];
|
if(it.second.empty()) {
|
||||||
int fps = atoi(argv[3]);
|
fprintf(stderr, "Missing argument '%s'\n", it.first.c_str());
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window src_window_id = strtol(args["-w"].c_str(), nullptr, 0);
|
||||||
|
const char *container_format = args["-c"].c_str();
|
||||||
|
int fps = atoi(args["-f"].c_str());
|
||||||
if(fps <= 0 || fps > 255) {
|
if(fps <= 0 || fps > 255) {
|
||||||
fprintf(stderr, "invalid fps argument: %s\n", argv[3]);
|
fprintf(stderr, "invalid fps argument: %s\n", args["-f"].c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +580,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||||
@ -719,7 +749,7 @@ int main(int argc, char **argv) {
|
|||||||
int window_height = xwa.height;
|
int window_height = xwa.height;
|
||||||
|
|
||||||
SoundDevice sound_device;
|
SoundDevice sound_device;
|
||||||
if(sound_device_get_by_name(&sound_device, "pulse", audio_stream->codec->channels, audio_stream->codec->frame_size) != 0) {
|
if(sound_device_get_by_name(&sound_device, args["-a"].c_str(), audio_stream->codec->channels, audio_stream->codec->frame_size) != 0) {
|
||||||
fprintf(stderr, "failed to get 'pulse' sound device\n");
|
fprintf(stderr, "failed to get 'pulse' sound device\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,55 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef PULSEAUDIO
|
||||||
|
#include <pulse/simple.h>
|
||||||
|
#include <pulse/error.h>
|
||||||
|
|
||||||
|
int sound_device_get_by_name(SoundDevice *device, const char *name, unsigned int num_channels, unsigned int period_frame_size) {
|
||||||
|
pa_sample_spec ss;
|
||||||
|
ss.format = PA_SAMPLE_S16LE;
|
||||||
|
ss.rate = 48000;
|
||||||
|
ss.channels = num_channels;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
pa_simple *pa_handle = pa_simple_new(nullptr, "gpu-screen-recorder", PA_STREAM_RECORD, name, "record", &ss, nullptr, nullptr, &error);
|
||||||
|
if(!pa_handle) {
|
||||||
|
fprintf(stderr, "pa_simple_new() failed: %s\n", pa_strerror(error));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int buffer_size = period_frame_size * 2 * num_channels; // 2 bytes/sample, @num_channels channels
|
||||||
|
void *buffer = malloc(buffer_size);
|
||||||
|
if(!buffer) {
|
||||||
|
fprintf(stderr, "failed to allocate buffer for audio\n");
|
||||||
|
pa_simple_free(pa_handle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Using pulseaudio\n");
|
||||||
|
|
||||||
|
device->handle = pa_handle;
|
||||||
|
device->buffer = buffer;
|
||||||
|
device->buffer_size = buffer_size;
|
||||||
|
device->frames = period_frame_size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_device_close(SoundDevice *device) {
|
||||||
|
pa_simple_free((pa_simple*)device->handle);
|
||||||
|
free(device->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sound_device_read_next_chunk(SoundDevice *device, void **buffer) {
|
||||||
|
int error;
|
||||||
|
if(pa_simple_read((pa_simple*)device->handle, device->buffer, device->buffer_size, &error) < 0) {
|
||||||
|
fprintf(stderr, "pa_simple_read() failed: %s\n", pa_strerror(error));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*buffer = device->buffer;
|
||||||
|
return device->frames;
|
||||||
|
}
|
||||||
|
#else
|
||||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
@ -52,7 +101,9 @@ int sound_device_get_by_name(SoundDevice *device, const char *name, unsigned int
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
device->handle = (void*)handle;
|
fprintf(stderr, "Using alsa\n");
|
||||||
|
|
||||||
|
device->handle = handle;
|
||||||
device->buffer = buffer;
|
device->buffer = buffer;
|
||||||
device->buffer_size = buffer_size;
|
device->buffer_size = buffer_size;
|
||||||
device->frames = frames;
|
device->frames = frames;
|
||||||
@ -83,7 +134,4 @@ int sound_device_read_next_chunk(SoundDevice *device, void **buffer) {
|
|||||||
*buffer = device->buffer;
|
*buffer = device->buffer;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
int sound_device_get_buffer_size(SoundDevice *device) {
|
|
||||||
return device->buffer_size;
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
[ "$#" -ne 3 ] && echo "usage: twitch-stream.sh <window_id> <fps> <livestream_key>" && exit 1
|
[ "$#" -ne 4 ] && echo "usage: twitch-stream.sh <window_id> <fps> <audio_input> <livestream_key>" && exit 1
|
||||||
sibs build --release && ./sibs-build/linux_x86_64/release/gpu-screen-recorder "$1" h264 "$2" | ffmpeg -i pipe:0 -c:v copy -f flv "rtmp://live.twitch.tv/app/$3"
|
#ismv
|
||||||
|
sibs build --release && ./sibs-build/linux_x86_64/release/gpu-screen-recorder -w "$1" -c flv -f "$2" -a "$3" | ffmpeg -i pipe:0 -c:v copy -f flv "rtmp://live.twitch.tv/app/$4"
|
||||||
|
Loading…
Reference in New Issue
Block a user