
Recherche avancée
Autres articles (101)
-
HTML5 audio and video support
13 avril 2011, parMediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
For older browsers the Flowplayer flash fallback is used.
MediaSPIP allows for media playback on major mobile platforms with the above (...) -
Contribute to translation
13 avril 2011You can help us to improve the language used in the software interface to make MediaSPIP more accessible and user-friendly. You can also translate the interface into any language that allows it to spread to new linguistic communities.
To do this, we use the translation interface of SPIP where the all the language modules of MediaSPIP are available. Just subscribe to the mailing list and request further informantion on translation.
MediaSPIP is currently available in French and English (...) -
Prérequis à l’installation
31 janvier 2010, parPréambule
Cet article n’a pas pour but de détailler les installations de ces logiciels mais plutôt de donner des informations sur leur configuration spécifique.
Avant toute chose SPIPMotion tout comme MediaSPIP est fait pour tourner sur des distributions Linux de type Debian ou dérivées (Ubuntu...). Les documentations de ce site se réfèrent donc à ces distributions. Il est également possible de l’utiliser sur d’autres distributions Linux mais aucune garantie de bon fonctionnement n’est possible.
Il (...)
Sur d’autres sites (8047)
-
send h264 video to nginx-rtmp server using ffmpeg API
11 décembre 2019, par GlenI have C++ code that grabs frames from a GigE camera and writes them out to a file. I’m using the libx264 codec and ffmpeg version 4.0.
Writing to the file works fine, however I would also like to send the video to nginx configured with the nginx-rtmp plug-in to make the video available live via HLS.
I can use the ffmpeg command line program to stream one of my previously captured files to my nginx server and rebroadcast as HLS, however if I try to stream from my C++ code the nginx server closes the connection after one or two frames are sent.
To test further, I used the ffmpeg command line program to receive a rtmp stream and write it out to a file. I am able to send video to ffmpeg from my C++ program with rtmp, however every frame generates a warning like this :
[avi @ 0x1b6b6f0] Non-monotonous DTS in output stream 0:0; previous: 1771, current: 53; changing to 1772. This may result in incorrect timestamps in the output file.
[avi @ 0x1b6b6f0] Non-monotonous DTS in output stream 0:0; previous: 1772, current: 53; changing to 1773. This may result in incorrect timestamps in the output file.
[avi @ 0x1b6b6f0] Non-monotonous DTS in output stream 0:0; previous: 1773, current: 53; changing to 1774. This may result in incorrect timestamps in the output file.
[avi @ 0x1b6b6f0] Non-monotonous DTS in output stream 0:0; previous: 1774, current: 53; changing to 1775. This may result in incorrect timestamps in the output file.
[avi @ 0x1b6b6f0] Non-monotonous DTS in output stream 0:0; previous: 1775, current: 53; changing to 1776. This may result in incorrect timestamps in the output file.
[avi @ 0x1b6b6f0] Non-monotonous DTS in output stream 0:0; previous: 1776, current: 53; changing to 1777. This may result in incorrect timestamps in the output file.
[avi @ 0x1b6b6f0] Non-monotonous DTS in output stream 0:0; previous: 1777, current: 53; changing to 1778. This may result in incorrect timestamps in the output file.
[avi @ 0x1b6b6f0] Non-monotonous DTS in output stream 0:0; previous: 1778, current: 53; changing to 1779. This may result in incorrect timestamps in the output file.
[avi @ 0x1b6b6f0] Non-monotonous DTS in output stream 0:0; previous: 1779, current: 53; changing to 1780. This may result in incorrect timestamps in the output file.I printed PTS and DTS for my packet before writing it, and the numbers were monotonous (for example, in this last frame the pts and dts printed from my code were 1780, not the ’current : 53’ that ffmpeg reports>
also, unless I tell ffmpeg what the output framerate should be I end up with a file that plays 2x speed.
After ffmpeg receives the rtmp stream and writes it to the file, I am then able to successfully send that file to my nginx server using ffmpeg.
here is some relevant code :
//configuring the codec context
// make sure that config.codec is something we support
// for now we are only supporting LIBX264
if (config.codec() != codecs::LIBX264) {
throw std::invalid_argument("currently only libx264 codec is supported");
}
// lookup specified codec
ffcodec_ = avcodec_find_encoder_by_name(config.codec().c_str());
if (!ffcodec_) {
throw std::invalid_argument("unable to get codec " + config.codec());
}
// unique_ptr to manage the codec_context
codec_context_ = av_pointer::codec_context(avcodec_alloc_context3(ffcodec_));
if (!codec_context_) {
throw std::runtime_error("unable to initialize AVCodecContext");
}
// setup codec_context_
codec_context_->width = frame_width;
codec_context_->height = frame_height;
codec_context_->time_base = (AVRational){1, config.target_fps()};
codec_context_->framerate = (AVRational){config.target_fps(), 1};
codec_context_->global_quality = 0;
codec_context_->compression_level = 0;
codec_context_->bits_per_raw_sample = 8;
codec_context_->gop_size = 1;
codec_context_->max_b_frames = 1;
codec_context_->pix_fmt = AV_PIX_FMT_YUV420P;
// x264 only settings
if (config.codec() == codecs::LIBX264) {
av_opt_set(codec_context_->priv_data, "preset", config.compression_target().c_str(), 0);
av_opt_set(codec_context_->priv_data, "crf", std::to_string(config.crf()).c_str(), 0);
}
// Open up the codec
if (avcodec_open2(codec_context_.get(), ffcodec_, NULL) < 0) {
throw std::runtime_error("unable to open ffmpeg codec");
}
// setup the output format context and stream for RTMP
AVFormatContext *tmp_f_context;
avformat_alloc_output_context2(&tmp_f_context, NULL, "flv", uri.c_str());
rtmp_format_context_ = av_pointer::format_context(tmp_f_context);
rtmp_stream_ = avformat_new_stream(rtmp_format_context_.get(), ffcodec_);
avcodec_parameters_from_context(rtmp_stream_->codecpar, codec_context_.get());
rtmp_stream_->time_base = codec_context_->time_base;
rtmp_stream_->r_frame_rate = codec_context_->framerate;
/* open the output file */
if (!(rtmp_format_context_->flags & AVFMT_NOFILE)) {
int r = avio_open(&rtmp_format_context_->pb, uri.c_str(), AVIO_FLAG_WRITE);
if (r < 0) {
throw std::runtime_error("unable to open " + uri + " : " + av_err2str(r));
}
}
if (avformat_write_header(rtmp_format_context_.get(), NULL) < 0) {
throw std::runtime_error("unable to write header");
}
av_dump_format(rtmp_format_context_.get(), 0,uri.c_str() , 1);at this point the av_dump_format produces this output :
Output #0, flv, to 'rtmp://[MY URI]':
Metadata:
encoder : Lavf58.12.100
Stream #0:0, 0, 1/1000: Video: h264 (libx264), 1 reference frame ([7][0][0][0] / 0x0007), yuv420p, 800x800 (0x0), 0/1, q=-1--1, 30 tbr, 1k tbnencoding and writing the frame :
// send the frame to the encoder, filtering first if necessary
void VideoWriter::Encode(AVFrame *frame)
{
int rval;
if (!apply_filter_) {
//send frame to encoder
rval = avcodec_send_frame(codec_context_.get(), frame);
if (rval < 0) {
throw std::runtime_error("error sending frame for encoding");
}
} else {
// push frame to filter
// REMOVED, currently testing without filtering
}
// get packets from encoder
while (rval >= 0) {
// create smart pointer to allocated packet
av_pointer::packet pkt(av_packet_alloc());
if (!pkt) {
throw std::runtime_error("unable to allocate packet");
}
rval = avcodec_receive_packet(codec_context_.get(), pkt.get());
if (rval == AVERROR(EAGAIN) || rval == AVERROR_EOF) {
return;
} else if (rval < 0) {
throw std::runtime_error("error during encoding");
}
// if I print pkt->pts and pkt->dts here, I see sequential numbers
// write packet
rval = av_interleaved_write_frame(rtmp_format_context_.get(), pkt.get());
if (rval < 0 ) {
std::cerr << av_err2str(rval) << std::endl;
}
}
}Since I am able to send video from a previously recorded file to nginx with the ffmpeg command line program, I believe the problem is in my code and not my nginx configuration.
EDIT : I think it may have to do with SPS/PPS as I see a bunch of these error messages in the nginx log before it closes the stream
2019/12/11 11:11:31 [error] 10180#0: *4 hls: failed to read 5 byte(s), client: XXX, server: 0.0.0.0:1935
2019/12/11 11:11:31 [error] 10180#0: *4 hls: error appenging SPS/PPS NALs, client: XXX, server: 0.0.0.0:1935As I mentioned, this code works fine if I set it up to write to an avi file rather stream to rtmp, and I can stream to ffmpeg listening for rtmp but with lots of warnings about the DTS but if I try to send to nginx, it closes the connection almost immediately. My first thought was that there was something wrong with the frame timestamps, but when I print pts and dts prior to writing the packet to the stream they look okay to me.
My end goal is to capture video to a file, and also be able to turn on the rtmp stream on demand — but for now I’m just trying to get the rtmp stream working continuously (without writing to a file)
Thanks for any insights.
-
Shell out to FFMPEG from Windows Service sometimes hangs
17 avril 2013, par Jake StevensonWe have a windows service which runs on multiple machines, waiting for MSMQ messages telling it to convert various files for us. Sometimes the files are video files and we shell out an ffmpeg process to do the conversion and wait for the process to complete or error before moving on. And on some occasions, that ffmpeg process appears to "hang" and we have to RDP to the machine as an admin and manually kill it off using task manager before it can continue to accept new messages. This hung ffmpeg process will stay that way indefinitely, I've waited several days on some occasions. The services all run under a special account.
The conversion process involves multiple steps— First copying the file locally, then running ffmpeg to convert, then running mp4box for "hinting", then another ffmpeg for a thumbnail. When it hangs, it is always on the first ffmpeg portion. Killing the ffmpeg process causes that code to receive an error and allows it to handle things normally from there.
Here is the code for that first FFMPEG process. As you can see, we've tried several things to detect a hung process :
public class FFMPEGEncoder : IEncoder
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern int SetErrorMode(int wMode);
private ILogger _logger = NullLogger.Instance;
public ILogger Logger
{
get { return _logger; }
set { _logger = value; }
}
private static readonly string ffmpeg = System.IO.Path.Combine(ConfigurationManager.AppSettings["FFMPEG_Dir"], "ffmpeg.exe");
private const string ffmpegArgs =
"-r 30000/1001 -b 200k -bt 240k -vcodec libx264 -coder 0 -bf 0 -flags2 -wpred-dct8x8 -level 13 -maxrate 768k -acodec libfaac -ac 2 -ar 48000 -ab 192k -s 480x320 -async 1";
public EncoderResult EncodeTheFile(string originalFile)
{
var newFileName =
VideoFileNameHelper.GetVideoFileName(originalFile);
Logger.Debug("Encoding {0} to {1} with ffmpeg", originalFile, newFileName);
RunEncoding(originalFile, newFileName);
return new EncoderResult { Filename = newFileName };
}
private void RunEncoding(string originalFile, string newFileName)
{
var process = new System.Diagnostics.Process
{
StartInfo =
{
CreateNoWindow = true,
WorkingDirectory = ConfigurationManager.AppSettings["FFMPEG_Dir"],
UseShellExecute = false,
FileName = ffmpeg,
Arguments = "-i \"" + originalFile + "\" " + ffmpegArgs + " \"" + newFileName + "\"",
RedirectStandardOutput = false,
RedirectStandardError = true
}
};
Logger.Debug("Launching ffmpeg with the following arguments:");
Logger.Debug(process.StartInfo.Arguments);
int oldMode = SetErrorMode(3);
var startTime = DateTime.Now;
process.Start();
var output = process.StandardError.ReadToEnd();
Logger.Debug("ffmpeg output:");
Logger.Debug(output);
while(!process.WaitForExit(3000))
{
if (!process.Responding)
{
process.Kill();
SetErrorMode(oldMode);
throw new Exception("Process hung");
}
if (DateTime.Now.Subtract(startTime) > new TimeSpan(0, 0, 30, 0))
{
process.Kill();
SetErrorMode(oldMode);
throw new Exception("Process hung");
}
}
SetErrorMode(oldMode);
var exitCode = process.ExitCode;
if (exitCode != 0)
{
//We got an error from ffmpeg
process.Close();
if (System.IO.File.Exists(newFileName))
{
System.IO.File.Delete(newFileName);
}
Logger.Error("Error converting video {0}", originalFile);
throw new Exception(string.Format("Unable to process the video {0}", originalFile));
}
process.Close();
}
}Despite the errormode setting code AND the code that tries to kill the process after 30 minutes, I still end up with it hung occasionally and have to manually kill the process. What am I doing wrong that would allow my system to more gracefully handle the "hung" ffmpeg processes ?
-
FFMPEG - format not available ?
16 mai 2013, par Julien GreardI'm converting some code from FFMPEG 0.8 to FFMPEG 1.2. I have an error during the call to the method avcodec_open2() : "Specified pixel format %s is invalid or not supported". The format I use is : AV_PIX_FMT_RGB24. It should be enabled by default, right ?
Below is my code :
av_register_all();
codec = avcodec_find_encoder(AV_CODEC_ID_MPEG2VIDEO);
if(!codec)
{
throw SystemException("codec not found");
}
codecContext = avcodec_alloc_context3(codec);
codecContext->bit_rate = 200000;
codecContext->time_base.den = 1;
codecContext->time_base.num = 90000;
codecContext->gop_size = 8;
codecContext->pix_fmt = AV_PIX_FMT_RGB24;
_codecContext->width = 320
_codecContext->height = 240
if(avcodec_open2(_codecContext, _codec, NULL) < 0)
{
throw SystemException("Unable to open codec");
}