1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

ffserver: add stream Metadata option

Also deprecate Author, Comment, Copyright, and Title options, and update
docs to use the new Metadata option.
This commit is contained in:
Stefano Sabatini 2013-11-29 08:41:24 +01:00
parent 33f10fa657
commit 9985710a5a
3 changed files with 51 additions and 35 deletions

View File

@ -235,7 +235,7 @@ StartSendOnKey
#<Stream test.ogg>
#Feed feed1.ffm
#Title "Stream title"
#Metadata title "Stream title"
#AudioBitRate 64
#AudioChannels 2
#AudioSampleRate 44100
@ -280,10 +280,10 @@ StartSendOnKey
#<Stream file.asf>
#File "/usr/local/httpd/htdocs/test.asf"
#NoAudio
#Author "Me"
#Copyright "Super MegaCorp"
#Title "Test stream from disk"
#Comment "Test comment"
#Metadata author "Me"
#Metadata copyright "Super MegaCorp"
#Metadata title "Test stream from disk"
#Metadata comment "Test comment"
#</Stream>

View File

@ -550,7 +550,11 @@ for regular streams.
@item Comment @var{value}
@item Copyright @var{value}
@item Title @var{value}
Set metadata corresponding to the option.
Set metadata corresponding to the option. All these options are
deprecated in favor of @option{Metadata}.
@item Metadata @var{key} @var{value}
Set metadata value on the output stream.
@item NoAudio
@item NoVideo
@ -757,7 +761,7 @@ Ogg Vorbis audio
@example
<Stream test.ogg>
Feed feed1.ffm
Title "Stream title"
Metadata title "Stream title"
AudioBitRate 64
AudioChannels 2
AudioSampleRate 44100
@ -804,10 +808,10 @@ NoAudio
<Stream file.asf>
File "/usr/local/httpd/htdocs/test.asf"
NoAudio
Author "Me"
Copyright "Super MegaCorp"
Title "Test stream from disk"
Comment "Test comment"
Metadata author "Me"
Metadata copyright "Super MegaCorp"
Metadata title "Test stream from disk"
Metadata comment "Test comment"
</Stream>
@end example
@end itemize

View File

@ -216,6 +216,7 @@ typedef struct FFStream {
struct FFStream *feed; /* feed we are using (can be null if
coming from file) */
AVDictionary *in_opts; /* input parameters */
AVDictionary *metadata; /* metadata to set on the stream */
AVInputFormat *ifmt; /* if non NULL, force input format */
AVOutputFormat *fmt;
IPAddressACL *acl;
@ -228,10 +229,6 @@ typedef struct FFStream {
int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
char feed_filename[1024]; /* file name of the feed storage, or
input file name for a stream */
char author[512];
char title[512];
char copyright[512];
char comment[512];
pid_t pid; /* Of ffmpeg process */
time_t pid_start; /* Of ffmpeg process */
char **child_argv;
@ -2279,11 +2276,7 @@ static int http_prepare_data(HTTPContext *c)
switch(c->state) {
case HTTPSTATE_SEND_DATA_HEADER:
memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
av_dict_set(&c->fmt_ctx.metadata, "author" , c->stream->author , 0);
av_dict_set(&c->fmt_ctx.metadata, "comment" , c->stream->comment , 0);
av_dict_set(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0);
av_dict_set(&c->fmt_ctx.metadata, "title" , c->stream->title , 0);
av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0);
c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
for(i=0;i<c->stream->nb_streams;i++) {
@ -2993,6 +2986,7 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
AVFormatContext *avc;
AVStream *avs = NULL;
AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
AVDictionaryEntry *entry = av_dict_get(stream->metadata, "title", NULL, 0);
int i;
avc = avformat_alloc_context();
@ -3001,7 +2995,7 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
}
avc->oformat = rtp_format;
av_dict_set(&avc->metadata, "title",
stream->title[0] ? stream->title : "No Title", 0);
entry ? entry->value : "No Title", 0);
avc->nb_streams = stream->nb_streams;
if (stream->is_multicast) {
snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
@ -4067,7 +4061,7 @@ static int parse_ffconfig(const char *filename)
FILE *f;
char line[1024];
char cmd[64];
char arg[1024];
char arg[1024], arg2[1024];
const char *p;
int val, errors, line_num;
FFStream **last_stream, *stream, *redirect;
@ -4367,18 +4361,37 @@ static int parse_ffconfig(const char *filename)
} else {
ERROR("FaviconURL only permitted for status streams\n");
}
} else if (!av_strcasecmp(cmd, "Author")) {
if (stream)
get_arg(stream->author, sizeof(stream->author), &p);
} else if (!av_strcasecmp(cmd, "Comment")) {
if (stream)
get_arg(stream->comment, sizeof(stream->comment), &p);
} else if (!av_strcasecmp(cmd, "Copyright")) {
if (stream)
get_arg(stream->copyright, sizeof(stream->copyright), &p);
} else if (!av_strcasecmp(cmd, "Title")) {
if (stream)
get_arg(stream->title, sizeof(stream->title), &p);
} else if (!av_strcasecmp(cmd, "Author") ||
!av_strcasecmp(cmd, "Comment") ||
!av_strcasecmp(cmd, "Copyright") ||
!av_strcasecmp(cmd, "Title")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
char key[32];
int i, ret;
for (i = 0; i < strlen(cmd); i++)
key[i] = av_tolower(cmd[i]);
key[i] = 0;
av_log(NULL, AV_LOG_WARNING,
"'%s' option in configuration file is deprecated, "
"use 'Metadata %s VALUE' instead\n", cmd, key);
if ((ret = av_dict_set(&stream->metadata, key, arg, 0)) < 0) {
ERROR("Could not set metadata '%s' to value '%s': %s\n",
key, arg, av_err2str(ret));
}
}
} else if (!av_strcasecmp(cmd, "Metadata")) {
get_arg(arg, sizeof(arg), &p);
get_arg(arg2, sizeof(arg2), &p);
if (stream) {
int ret;
if ((ret = av_dict_set(&stream->metadata, arg, arg2, 0)) < 0) {
ERROR("Could not set metadata '%s' to value '%s': %s\n",
arg, arg2, av_err2str(ret));
}
}
} else if (!av_strcasecmp(cmd, "Preroll")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
@ -4501,7 +4514,6 @@ static int parse_ffconfig(const char *filename)
}
} else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
!av_strcasecmp(cmd, "AVOptionAudio")) {
char arg2[1024];
AVCodecContext *avctx;
int type;
get_arg(arg, sizeof(arg), &p);