
Recherche avancée
Autres articles (36)
-
Les autorisations surchargées par les plugins
27 avril 2010, parMediaspip core
autoriser_auteur_modifier() afin que les visiteurs soient capables de modifier leurs informations sur la page d’auteurs -
MediaSPIP Player : problèmes potentiels
22 février 2011, parLe lecteur ne fonctionne pas sur Internet Explorer
Sur Internet Explorer (8 et 7 au moins), le plugin utilise le lecteur Flash flowplayer pour lire vidéos et son. Si le lecteur ne semble pas fonctionner, cela peut venir de la configuration du mod_deflate d’Apache.
Si dans la configuration de ce module Apache vous avez une ligne qui ressemble à la suivante, essayez de la supprimer ou de la commenter pour voir si le lecteur fonctionne correctement : /** * GeSHi (C) 2004 - 2007 Nigel McNie, (...) -
Keeping control of your media in your hands
13 avril 2011, parThe vocabulary used on this site and around MediaSPIP in general, aims to avoid reference to Web 2.0 and the companies that profit from media-sharing.
While using MediaSPIP, you are invited to avoid using words like "Brand", "Cloud" and "Market".
MediaSPIP is designed to facilitate the sharing of creative media online, while allowing authors to retain complete control of their work.
MediaSPIP aims to be accessible to as many people as possible and development is based on expanding the (...)
Sur d’autres sites (6607)
-
VLC and ffplay not receiving video from RTMP stream on Nginx
14 janvier, par EkobaddI'm streaming via OBS 30.1.2 to an RTMP server on a digitalocean droplet. The server is running on nginx 1.26.0 using the RTMP plugin (libnginx-mod-rtmp in apt).


OBS is configured to output H.264-encoded, 1200kbps, 24fps, 1920x1080 video and aac-encoded, stereo, 44.1kHz, 160kbps audio.


Below is the minimal reproducible example. When I attempt to play the rtmp stream with ffplay or VLC, it's a random chance whether I get video or not. Audio is always fine. The output from ffplay or ffprobe (example below) occasionally does not show any video stream.


rtmp {
 server {
 listen 1935;
 chunk_size 4096;

 application ingest {
 live on;
 record off;

 allow publish <my ip="ip" address="address">;
 deny publish all;

 allow play all;
 }
 }
}
</my>


The server has two applications, "ingest" and "live", the former uses the following ffmpeg command to transcode the stream and create a corresponding stream on the latter application :


exec_push ffmpeg -i rtmp://localhost/ingest/$name -b:v 1200k -c:v libx264 -c:a aac -ar 44100 -ac 1 -f flv -preset veryfast -tune zerolatency rtmp://localhost/live/$name 2>>/tmp/rtmp-ingest-$name.log;



As you can see, this produces a log which shows the following :


Output #0, flv, to 'rtmp://localhost/live/ekobadd':
 Metadata:
 |RtmpSampleAccess: true
 Server : NGINX RTMP (github.com/arut/nginx-rtmp-module)
 displayWidth : 1920
 displayHeight : 1080
 fps : 23
 profile :
 level :
 encoder : Lavf61.1.100
 Stream #0:0: Audio: aac (LC) ([10][0][0][0] / 0x000A), 44100 Hz, mono, fltp, 69 kb/s
 Metadata:
 encoder : Lavc61.3.100 aac



The video is not present, though I can see on the digitalocean control panel that the server is pulling 1.2Mbps inbound, which is about the same as my OBS video bitrate. And, although the ffmpeg instance which is transcoding does not appear to see the video stream from the ingest application, ffprobe from my local machine does, sometimes :


> ffprobe rtmp://mydomain.com/ingest/ekobadd
...
Input #0, flv, from 'rtmp://mydomain.com/ingest/ekobadd': 0B f=0/0
 Metadata:
 |RtmpSampleAccess: true
 Server : NGINX RTMP (github.com/arut/nginx-rtmp-module)
 displayWidth : 1920
 displayHeight : 1080
 fps : 23
 profile :
 level :
 Duration: 00:00:00.00, start: 122.045000, bitrate: N/A
 Stream #0:0: Audio: aac (LC), 48000 Hz, stereo, fltp, 163 kb/s
 Stream #0:1: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 1228 kb/s, 23 fps, 23.98 tbr, 1k tbn
 126.24 A-V: -1.071 fd= 0 aq= 54KB vq= 161KB sq= 0B f=0/0



Sometimes, however, it doesn't see the stream at all :


[rtmp @ 0000022d87d0fe00] Server error: No such stream
rtmp://mydomain.com/ingest/ekobadd: Operation not permitted



Testing the stream with VLC gives the same results.


Of course, the "live" application also doesn't have video. I have, however, streamed video from it before. I assume if I restart nginx enough, that the exec_push ffmpeg command will randomly see the video stream much like ffprobe does. I also have HLS and DASH configured, and they're both working perfect if you're a radio talk show host.


/etc/nginx/nginx.conf : (I'm quite sure I never touched anything in the HTTP section, but it's included just in case)


rtmp {
 server {
 listen 1935;
 chunk_size 8192;

 idle_streams off;

 application ingest {
 live on;
 record off;

 # Transcode to h264/aac via flv, 1.2Mbps 24fps 44.1kHz, single audio channel video (HLS Ready)
 exec_push ffmpeg -i rtmp://localhost/ingest/$name -b:v 1200k -c:v libx264 -c:a aac -ar 44100 -ac 1 -f flv -preset veryfast -tune zerolatency rtmp://localhost/live/$name 2>>/tmp/rtmp-ingest-$name.log;

 allow publish <my ip="ip" address="address">;
 deny publish all;

 allow play all; # This was added for debugging.
 }

 application live {
 live on;
 record off;

 hls on;
 hls_path /var/www/mydomain.com/html/live/hls;
 hls_fragment 6s;
 hls_playlist_length 60;

 dash on;
 dash_path /var/www/mydomain.com/html/live/dash;

 allow publish 127.0.0.1;
 deny publish all;

 allow play all;
 }
 }
}

http {

 ##
 # Basic Settings
 ##

 sendfile on;
 tcp_nopush on;
 types_hash_max_size 2048;
 server_tokens build; # Recommended practice is to turn this off

 server_names_hash_bucket_size 64;
 # server_name_in_redirect off;

 include /etc/nginx/mime.types;
 default_type application/octet-stream;

 ##
 # SSL Settings
 ##

 ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3 (POODLE), TLS 1.0, 1.1
 ssl_prefer_server_ciphers off; # Don't force server cipher order.

 ##
 # Logging Settings
 ##

 access_log /var/log/nginx/access.log;

 ##
 # Gzip Settings
 ##

 gzip on;

 # gzip_vary on;
 # gzip_proxied any;
 # gzip_comp_level 6;
 # gzip_buffers 16 8k;
 # gzip_http_version 1.1;
 # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

 ##
 # Virtual Host Configs
 ##

 include /etc/nginx/conf.d/*.conf;
 include /etc/nginx/sites-enabled/*;
}
</my>


/etc/nginx/sites-available/mydomain.com :


server {
 listen 443 ssl;

 ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
 ssl_ciphers HIGH:!aNULL:!MD5;

 root /var/www/mydomain.com/html;

 server_name mydomain.com www.mydomain.com;

 location / {
 root /var/www/mydomain.com/html/live;

# add_header Cache-Control no-cache;
 add_header Access-Control-Allow-Origin *;
 }
}

types {
# application/vnd.apple.mpegurl m3u8;
 application/dash+xml mpd;
}



-
ffmpeg-next potential bug in write_header causes timebase to bet set to Rational(1/15360)
7 septembre 2024, par HuhngutI am trying to encode a video using the ffmpeg_next crate. I got everything working and it successfully creates an output video.
The only problem is that the time_base of my stream is wrongly written to the file.
I can confirm that I set the timebase correctly for both the encoder as well as the stream.


By debug prints I was able to narrow the problem down.
octx.write_header().unwrap();
causes the stream timebase to be reset from Rational(1/30) to Rational(1/15360). Changing the timebase back afterwards has no effect. The wrong value must have been written to the header.

I modified the src code of ffmpeg-next and recompiled it. I can confirm that the correct value is set before the call to
avformat_write_header


pub fn write_header(&mut self) -> Result<(), Error> {
 println!(
 "_________________ {:?}",
 self.stream(0).unwrap().time_base()
 );
 unsafe {
 match avformat_write_header(self.as_mut_ptr(), ptr::null_mut()) {
 0 => Ok(()),
 e => Err(Error::from(e)),
 }
 }
 }



To my understanding this must be a bug in the crate but I dont want to accuse someone with my non existing knowledge about ffmpeg. Also the examples in the github repo seem not to have this problem. My fault then ? Unfortunately I was not able to get the transcode-x264 to run. Most of my code comes from this example.


Relevant code bits are these. I dont know how much the set_parameters influences anything. My testing said it has no influence. I also tried to set the timebase at the very end of the function if it gets reset my the parameters. This is not working


let mut ost = octx.add_stream(codec)?;
ost.set_time_base(Rational::new(1, FPS));

ost.set_parameters(&encoder);
encoder.set_time_base(Rational::new(1, FPS));
ost.set_parameters(&opened_encoder);



By default and in the above example the streams timebase is 0/0. If I leave it out or change it to this manually it has no effect.


I also noticed that changing the value inside set_pts influences the output fps. Although not the timebase. I think this is more of a sideeffect.


I will leave a minimal reproducible example below. Any help or hints would be appreciated


abstract main function


fn main() {
 let output_file = "output.mp4";
 let x264_opts = parse_opts("preset=medium".to_string()).expect("invalid x264 options string");

 ffmpeg_next::init().unwrap();
 let mut octx = format::output(output_file).unwrap();

 let mut encoder = Encoder::new(&mut octx, x264_opts).unwrap();

 format::context::output::dump(&octx, 0, Some(&output_file));
 //This line somehow clears the streams time base
 octx.write_header().unwrap();

 // Without this line, the next logs returns Rational(1/30) Rational(1/15360) indicating streams timebase is wrong. even thought I set it above
 // this line changes it back but only for the print but not the actual output. Because the faulty data is written into the header
 // octx.stream_mut(0)
 // .unwrap()
 // .set_time_base(Rational::new(1, FPS));

 println!(
 "---------------- {:?} {:?}",
 encoder.encoder.time_base(),
 octx.stream(0).unwrap().time_base(),
 );

 for frame_num in 0..100 {
 let mut frame = encoder.create_frame();
 frame.set_pts(Some(frame_num));
 encoder.add_frame(&frame, &mut octx);
 }

 encoder.close(&mut octx);
 octx.write_trailer().unwrap();
}



Encoder struct containing the implementation logic


struct Encoder {
 encoder: encoder::Video,
}

impl Encoder {
 fn new(
 octx: &mut format::context::Output,
 x264_opts: Dictionary,
 ) -> Result {
 let set_header = octx
 .format()
 .flags()
 .contains(ffmpeg_next::format::flag::Flags::GLOBAL_HEADER);

 let codec = encoder::find(codec::Id::H264);
 let mut ost = octx.add_stream(codec)?;
 ost.set_time_base(Rational::new(1, FPS));

 let mut encoder = codec::context::Context::new_with_codec(
 encoder::find(codec::Id::H264)
 .ok_or(ffmpeg_next::Error::InvalidData)
 .unwrap(),
 )
 .encoder()
 .video()
 .unwrap();
 ost.set_parameters(&encoder);

 encoder.set_width(WIDTH);
 encoder.set_height(HEIGHT);
 encoder.set_aspect_ratio(WIDTH as f64 / HEIGHT as f64);
 encoder.set_format(util::format::Pixel::YUV420P);
 encoder.set_frame_rate(Some(Rational::new(FPS, 1)));
 encoder.set_time_base(Rational::new(1, FPS));

 if set_header {
 encoder.set_flags(ffmpeg_next::codec::flag::Flags::GLOBAL_HEADER);
 }

 let opened_encoder = encoder
 .open_with(x264_opts.to_owned())
 .expect("error opening x264 with supplied settings");
 ost.set_parameters(&opened_encoder);

 println!(
 "\nost time_base: {}; encoder time_base: {}; encoder frame_rate: {}\n",
 ost.time_base(),
 &opened_encoder.time_base(),
 &opened_encoder.frame_rate()
 );

 Ok(Self {
 encoder: opened_encoder,
 })
 }

 fn add_frame(&mut self, frame: &frame::Video, octx: &mut format::context::Output) {
 self.encoder.send_frame(frame).unwrap();
 self.process_packets(octx);
 }

 fn close(&mut self, octx: &mut format::context::Output) {
 self.encoder.send_eof().unwrap();
 self.process_packets(octx);
 }

 fn process_packets(&mut self, octx: &mut format::context::Output) {
 let mut encoded = Packet::empty();
 while self.encoder.receive_packet(&mut encoded).is_ok() {
 encoded.set_stream(0);
 encoded.write_interleaved(octx).unwrap();
 }
 }

 fn create_frame(&self) -> frame::Video {
 return frame::Video::new(
 self.encoder.format(),
 self.encoder.width(),
 self.encoder.height(),
 );
 }
}



other util stuff


use ffmpeg_next::{
 codec::{self},
 encoder, format, frame, util, Dictionary, Packet, Rational,
};

const FPS: i32 = 30;
const WIDTH: u32 = 720;
const HEIGHT: u32 = 1080;

fn parse_opts<'a>(s: String) -> Option> {
 let mut dict = Dictionary::new();
 for keyval in s.split_terminator(',') {
 let tokens: Vec<&str> = keyval.split('=').collect();
 match tokens[..] {
 [key, val] => dict.set(key, val),
 _ => return None,
 }
 }
 Some(dict)
}



-
aaccoder : Implement Perceptual Noise Substitution for AAC
15 avril 2015, par Rostislav Pehlivanovaaccoder : Implement Perceptual Noise Substitution for AAC
This commit implements the perceptual noise substitution AAC extension. This is a proof of concept
implementation, and as such, is not enabled by default. This is the fourth revision of this patch,
made after some problems were noted out. Any changes made since the previous revisions have been indicated.In order to extend the encoder to use an additional codebook, the array holding each codebook has been
modified with two additional entries - 13 for the NOISE_BT codebook and 12 which has a placeholder function.
The cost system was modified to skip the 12th entry using an array to map the input and outputs it has. It
also does not accept using the 13th codebook for any band which is not marked as containing noise, thereby
restricting its ability to arbitrarily choose it for bands. The use of arrays allows the system to be easily
extended to allow for intensity stereo encoding, which uses additional codebooks.The 12th entry in the codebook function array points to a function which stops the execution of the program
by calling an assert with an always ’false’ argument. It was pointed out in an email discussion with
Claudio Freire that having a ’NULL’ entry can result in unexpected behaviour and could be used as
a security hole. There is no danger of this function being called during encoding due to the codebook maps introduced.Another change from version 1 of the patch is the addition of an argument to the encoder, ’-aac_pns’ to
enable and disable the PNS. This currently defaults to disable the PNS, as it is experimental.
The switch will be removed in the future, when the algorithm to select noise bands has been improved.
The current algorithm simply compares the energy to the threshold (multiplied by a constant) to determine
noise, however the FFPsyBand structure contains other useful figures to determine which bands carry noise more accurately.Some of the sample files provided triggered an assertion when the parameter to tune the threshold was set to
a value of ’2.2’. Claudio Freire reported the problem’s source could be in the range of the scalefactor
indices for noise and advised to measure the minimal index and clip anything above the maximum allowed
value. This has been implemented and all the files which used to trigger the asserion now encode without error.The third revision of the problem also removes unneded variabes and comparisons. All of them were
redundant and were of little use for when the PNS implementation would be extended.The fourth revision moved the clipping of the noise scalefactors outside the second loop of the two-loop
algorithm in order to prevent their redundant calculations. Also, freq_mult has been changed to a float
variable due to the fact that rounding errors can prove to be a problem at low frequencies.
Considerations were taken whether the entire expression could be evaluated inside the expression
, but in the end it was decided that it would be for the best if just the type of the variable were
to change. Claudio Freire reported the two problems. There is no change of functionality
(except for low sampling frequencies) so the spectral demonstrations at the end of this commit’s message were not updated.Finally, the way energy values are converted to scalefactor indices has changed since the first commit,
as per the suggestion of Claudio Freire. This may still have some drawbacks, but unlike the first commit
it works without having redundant offsets and outputs what the decoder expects to have, in terms of the
ranges of the scalefactor indices.Some spectral comparisons : https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/Original.png (original),
https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/PNS_NO.png (encoded without PNS),
https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/PNS1.2.png (encoded with PNS, const = 1.2),
https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/Difference1.png (spectral difference).
The constant is the value which multiplies the threshold when it gets compared to the energy, larger
values means more noise will be substituded by PNS values. Example when const = 2.2 :
https://trac.ffmpeg.org/attachment/wiki/Encode/AAC/PNS_2.2.pngReviewed-by : Claudio Freire <klaussfreire@gmail.com>
Signed-off-by : Michael Niedermayer <michaelni@gmx.at>