Commit 563e9fd3 authored by Julian Rother's avatar Julian Rother
Browse files

Added complex_live_transcode

parent ac3ae29c
TARGETS = probe probe-raw remux thumbnail transcode publish_video simple_live_transcode live_forward
TARGETS = probe probe-raw remux thumbnail transcode publish_video simple_live_transcode live_forward complex_live_transcode
CFLAGS = -I /usr/include/libxml2
LDFLAGS= -lcurl -lavcodec -lavformat -lavfilter -lswscale -lavutil -lxml2
......@@ -20,6 +20,8 @@ publish_video: publish_video.c *.h util/*.c
simple_live_transcode: simple_live_transcode.c *.h util/*.c
complex_live_transcode: complex_live_transcode.c *.h util/*.c
live_forward: live_forward.c *.h util/*.c
#include <poll.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "util.h"
#define OUTPUT_FORMAT(bitrate) "-f", "flv", "-r", "25", "-c:v", "libx264", "-b:v", bitrate, "-bufsize", bitrate, "-preset", "veryfast", "-x264-params", "keyint=125:min-keyint=125:no-scenecut", "-c:a", "aac"
static void copy_to_log(int fd)
static char buf[1024];
size_t len;
if ((len = read(fd, BL(buf))) > 0)
fwrite(buf, 1, len, logstream);
int main(int argc, char *argv[])
int ret, canceled = 0, errpipe[2] = {-1, -1};
char *src1, *src2, *src1fmt = "flv", *src2fmt = "flv", *dest, *logo_expr;
pid_t pid;
struct pollfd fds = {.fd = -1, .events = POLLIN};
if (argc != 5)
return 1;
jobid = atoi(argv[1]);
src1 = jlookup(argv[4], "src1");
src2 = jlookup(argv[4], "src2");
if (!jstr(jlookup(src1, "url"), 0))
src1fmt = "lavfi";
if (!jstr(jlookup(src2, "url"), 0))
src2fmt = "lavfi";
dest = jstr(jlookup(argv[4], "destbase"), "rtmp://");
if (jint(jlookup(argv[4], "videoag_logo"), 1))
logo_expr = "overlay=x=W-195:y=H-155";
logo_expr = "overlay=x=W+1000:y=H+1000";
if (!(pid = fork()))
dup2(errpipe[1], 2); close(errpipe[1]);
dup2(open("/dev/null", O_RDONLY|O_CLOEXEC), 0);
dup2(open("/dev/null", O_WRONLY|O_CLOEXEC), 1);
execlp("ffmpeg", "ffmpeg", "-nostats",
"-f", src1fmt, "-i", jstr(jlookup(src1, "url"), "smptehdbars[out0]; anullsrc[out1]"),
"-f", src2fmt, "-i", jstr(jlookup(src2, "url"), "smptehdbars[out0]; anullsrc[out1]"),
mprintf("[0:a]%s[a1]; [1:a]%s[a2]; [a1][a2]amix,%s,asplit=3[lowa][mida][higha];"
"[0:v]%s[v1]; [1:v]%s[v2]; [v1][v2]%s,scale=1920:1080[tmp];"
jstr(jlookup(src1, "afilter"), "acopy"),
jstr(jlookup(src2, "afilter"), "acopy"),
jstr(jlookup(argv[4], "afilter"), "acopy"),
jstr(jlookup(src1, "vfilter"), "copy"),
jstr(jlookup(src2, "vfilter"), "copy"),
jstr(jlookup(argv[4], "vmix"), "streamselect=map=0"),
getenv(WORKER_RAW), logo_expr
"-map", "[low]", "-map", "[lowa]", OUTPUT_FORMAT("512k"), mprintf("%s_low", dest),
"-map", "[mid]", "-map", "[mida]", OUTPUT_FORMAT("2024k"), mprintf("%s_mid", dest),
"-map", "[high]", "-map", "[higha]", OUTPUT_FORMAT("6024k"), mprintf("%s_high", dest), 0);
fds.fd = errpipe[0];
while (1)
canceled = ping_job(jobid, "running", "{\"log\": \"%s\"}", jescape(get_avlogbuf()));
if (canceled == 1)
kill(pid, SIGINT); /* Stop ffmpeg */
poll(&fds, 1, 15000);
if (fds.revents & POLLIN)
else if (fds.revents & (POLLERR|POLLHUP|POLLNVAL))
waitpid(pid, &ret, 0);
if (canceled == 1 && (WEXITSTATUS(ret) == 255 || (WIFSIGNALED(ret) && WTERMSIG(ret) == SIGINT)))
ping_job(jobid, "finished", "{\"log\": \"%s\"}", jescape(get_avlogbuf()));
else if (WIFSIGNALED(ret))
job_failed("Subprocesses was killed by signal %s (%i)", strsignal(WTERMSIG(ret)), WTERMSIG(ret));
job_failed("Subprocesses terminated with exit status %i", WEXITSTATUS(ret));
return 0;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment