Skip to content
Snippets Groups Projects
Commit f1cf6092 authored by Julian Rother's avatar Julian Rother
Browse files

Added live_forward

parent 44ef50f7
No related branches found
No related tags found
No related merge requests found
Pipeline #181 passed
TARGETS = probe probe-raw remux thumbnail transcode publish_video simple_live_transcode
TARGETS = probe probe-raw remux thumbnail transcode publish_video simple_live_transcode live_forward
CFLAGS = -I /usr/include/libxml2
LDFLAGS= -lcurl -lavcodec -lavformat -lavfilter -lswscale -lavutil -lxml2
......@@ -20,5 +20,7 @@ publish_video: publish_video.c *.h util/*.c
simple_live_transcode: simple_live_transcode.c *.h util/*.c
live_forward: live_forward.c *.h util/*.c
clean:
rm -f ${TARGETS}
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include "util.h"
int main(int argc, char *argv[])
{
int i, err, canceled;
int *idxmap;
char *src, *dest;
AVFormatContext *demux, *mux;
AVPacket pkt;
AVStream *stream;
AVDictionary *muxopts;
if (argc != 5)
return 1;
av_register_all();
avformat_network_init();
init_env();
init_avlogbuf();
memset(&pkt, 0, sizeof(pkt));
av_init_packet(&pkt);
jobid = atoi(argv[1]);
src = jstr(jlookup(argv[4], "src"), "rtmp://example.com:99999/notfound");
dest = jstr(jlookup(argv[4], "dest"), "rtmp://example.com:99999/notfound");
ping_job(jobid, "running", 0);
demux = 0;
if (err = avformat_open_input(&demux, src, 0, 0))
job_failed("Opening input stream failed: %s", av_err2str(err));
avformat_find_stream_info(demux, 0);
err = avformat_alloc_output_context2(&mux,
av_guess_format(jstr(jlookup(argv[4], "format"), 0), dest, 0), 0, dest);
if (err < 0)
job_failed("Error allocating muxer context: %s", av_err2str(err));
av_dict_copy(&mux->metadata, demux->metadata, 0);
parse_dict(&mux->metadata, jlookup(argv[4], "metadata"));
idxmap = malloc(sizeof(int)*demux->nb_streams);
for (i = 0; i < demux->nb_streams; i ++)
{
idxmap[i] = -1;
if (demux->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO
&& demux->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO
&& demux->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
continue;
stream = avformat_new_stream(mux, 0);
av_dict_copy(&stream->metadata, mux->streams[i]->metadata, 0);
idxmap[i] = stream->index;
avcodec_parameters_copy(mux->streams[i]->codecpar,
demux->streams[i]->codecpar);
mux->streams[i]->codecpar->codec_tag = 0;
mux->streams[i]->time_base = demux->streams[i]->time_base;
}
muxopts = 0;
parse_dict(&muxopts, jlookup(argv[4], "options"));
if ((err = avformat_write_header(mux, &muxopts)) < 0)
job_failed("Writing header failed: %s", av_err2str(err));
canceled = 0;
while (!canceled && !av_read_frame(demux, &pkt))
{
if (!checktime(30))
canceled = ping_job(jobid, "running", 0);
if (pkt.stream_index >= demux->nb_streams
|| idxmap[pkt.stream_index] == -1)
continue;
pkt.stream_index = idxmap[pkt.stream_index];
pkt.pts = av_rescale_q_rnd(pkt.pts, demux->streams[pkt.stream_index]->time_base,
mux->streams[pkt.stream_index]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.dts = av_rescale_q_rnd(pkt.dts, demux->streams[pkt.stream_index]->time_base,
mux->streams[pkt.stream_index]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.duration = av_rescale_q(pkt.duration, demux->streams[pkt.stream_index]->time_base,
mux->streams[pkt.stream_index]->time_base);
pkt.pos = -1;
if (err = av_interleaved_write_frame(mux, &pkt))
job_failed("Could not write frame: %s", av_err2str(err));
}
avformat_close_input(&demux);
av_interleaved_write_frame(mux, 0);
if (err = av_write_trailer(mux))
job_failed("Error writing trailer", av_err2str(err));
ping_job(jobid, "finished", "{%s, \"log\": \"%s\"}", jescape(get_avlogbuf()));
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment