
Recherche avancée
Médias (1)
-
Carte de Schillerkiez
13 mai 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Texte
Autres articles (52)
-
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 -
Publier sur MédiaSpip
13 juin 2013Puis-je poster des contenus à partir d’une tablette Ipad ?
Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir -
Support audio et vidéo HTML5
10 avril 2011MediaSPIP utilise les balises HTML5 video et audio pour la lecture de documents multimedia en profitant des dernières innovations du W3C supportées par les navigateurs modernes.
Pour les navigateurs plus anciens, le lecteur flash Flowplayer est utilisé.
Le lecteur HTML5 utilisé a été spécifiquement créé pour MediaSPIP : il est complètement modifiable graphiquement pour correspondre à un thème choisi.
Ces technologies permettent de distribuer vidéo et son à la fois sur des ordinateurs conventionnels (...)
Sur d’autres sites (12689)
-
ffmpeg how to ignore initial empty audio frames when decoding to loop a sound
1er décembre 2020, par cs guyI am trying to loop a ogg sound file. The goal is to make a loopable audio interface for my mobile app.


I decode the given ogg file into a buffer and that buffer is sent to audio card for playing. All good until it the audio finishes (end of file). When it finishes I use
av_seek_frame(avFormatContext, streamInfoIndex, 0, AVSEEK_FLAG_FRAME);
to basically loop back to beginning. And continue decoding into writing to the same buffer. At first sight I thought this would give me perfect loops. One problem I had was, the decoder in the end gives me extra empty frames. So I ignored them by keeping track of how many samples are decoded :

durationInMillis = avFormatContext->duration * 1000;
numOfTotalSamples =
 (uint64_t) avFormatContext->duration *
 (uint64_t) pLocalCodecParameters->sample_rate *
 (uint64_t) pLocalCodecParameters->channels /
 (uint64_t) AV_TIME_BASE;



When the threshold is reached I ignore the frames sent by the codec. I thought this was it and ran some test. I recorded 5 minutes of my app and in the end I compared the results in FL studio by customly adding the same sound clip several times to match the length of my audio recording :


Here it is after 5 minutes :




In the first loops the difference is very low I thought it was working and I used this for several days until I tested this on 5 minute recording. As the looping approached to 5 minutes mark the difference got very huge. My code is not looping the audio correctly. I suspect that the codec is adding 1 or 2 empty frames at the very beginning in each loop caused by
av_seek_frame
knowing that a frame can contain up several audio samples. These probably accumulate and cause the mismatch.

My question is : how can I drop the empty frames that is sent by codec while decoding so that I can create a perfect loop of the audio ?


My code is below here. Please be aware that I deleted lots of if checks that was inteded for safety to make it more readable in the code below, these removed checks are always false so it doesnt matter for the reader.


helper.cpp


int32_t
outputAudioFrame(AVCodecContext *avCodecContext, AVFrame *avResampledDecFrame, int32_t &ret,
 LockFreeQueue<float> *&buffer, int8_t *&mediaLoadPointer,
 AVFrame *avDecoderFrame, SwrContext *swrContext,
 std::atomic_bool *&signalExitFuture,
 uint64_t &currentNumSamples, uint64_t &numOfTotalSamples) {
 // resampling is done here but its boiler code so I removed it.
 auto *floatArrPtr = (float *) (avResampledDecFrame->data[0]);

 int32_t numOfSamples = avResampledDecFrame->nb_samples * avResampledDecFrame->channels;

 for (int32_t i = 0; i < numOfSamples; i++) {
 if (currentNumSamples == numOfTotalSamples) {
 break;
 }

 buffer->push(*floatArrPtr);
 currentNumSamples++;
 floatArrPtr++;
 }

 return 0;
}



int32_t decode(int32_t &ret, AVCodecContext *avCodecContext, AVPacket *avPacket,
 LockFreeQueue<float> *&buffer,
 AVFrame *avDecoderFrame,
 AVFrame *avResampledDecFrame,
 std::atomic_bool *&signalExitFuture,
 int8_t *&mediaLoadPointer, SwrContext *swrContext,
 uint64_t &currentNumSamples, uint64_t &numOfTotalSamples) {
 
 ret = avcodec_send_packet(avCodecContext, avPacket);
 if (ret < 0) {
 LOGE("decode: Error submitting a packet for decoding %s", av_err2str(ret));
 return ret;
 }

 // get all the available frames from the decoder
 while (ret >= 0) {

 // submit the packet to the decoder
 ret = avcodec_receive_frame(avCodecContext, avDecoderFrame);
 if (ret < 0) {
 // those two return values are special and mean there is no output
 // frame available, but there were no errors during decoding
 if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) {
 //LOGD("avcodec_receive_frame returned special %s", av_err2str(ret));
 return 0;
 }

 LOGE("avcodec_receive_frame Error during decoding %s", av_err2str(ret));
 return ret;
 }

 ret = outputAudioFrame(avCodecContext, avResampledDecFrame, ret, buffer,
 mediaLoadPointer, avDecoderFrame, swrContext, signalExitFuture,
 currentNumSamples, numOfTotalSamples);

 av_frame_unref(avDecoderFrame);
 av_frame_unref(avResampledDecFrame);

 if (ret < 0)
 return ret;
 }

 return 0;
}
</float></float>


Main.cpp


while (!*signalExitFuture) {
 while ((ret = av_read_frame(avFormatContext, avPacket)) >= 0) {

 ret = decode(ret, avCodecContext, avPacket, buffer, avDecoderFrame,
 avResampledDecFrame, signalExitFuture,
 mediaLoadPointer, swrContext,
 currentNumSamples, numOfTotalSamples);

 // The packet must be freed with av_packet_unref() when it is no longer needed.
 av_packet_unref(avPacket);

 if (ret < 0) {
 LOGE("Error! %s", av_err2str(ret));

 goto cleanup;
 }
 }

 if (ret == AVERROR_EOF) {

 ret = av_seek_frame(avFormatContext, streamInfoIndex, 0, AVSEEK_FLAG_FRAME);

 currentNumSamples = 0;
 avcodec_flush_buffers(avCodecContext);
 }
 }



-
Render SharpDX Texture2D in UWP application
10 décembre 2019, par AlexI’m implementing a solution for hardware-accelerated H264 decoding and rendering in the UWP application. I want to avoid copying from GPU to CPU.
The solutions consists of 2 parts :- C library that decodes the H264 stream using ffmpeg
- UWP/C#/SharpDX application to receive encoded data, pinvoke library and then render decoded frames.
I receive encoded data in the C# application and send it to the C library to decode and get the pointer to the frame back using pinvoke.
C part looks good so far. I managed to receive pointer to the decoded frame in GPU in the C library :
// ffmpeg decoding logic
ID3D11Texture2D* texturePointer = (ID3D11Texture2D*)context->frame->data[0];I managed to receive this pointer in C# code and create SharpDX texture from it.
var texturePointer = decoder.Decode(...data...); // pinvoke
if (texturePointer != IntPtr.Zero)
{
var texture = new Texture2D(texturePointer); // works just perfect
}Now I need to render it on the screen. My understanding is that I can create class that extends
SurfaceImageSource
so I can assign it as aSource
of XAMLImage
object.
It can be something like this :public class RemoteMediaImageSource : SurfaceImageSource
{
public void BeginDraw(IntPtr texturePointer)
{
var texture = new Texture2D(texturePointer);
// What to do to render texture in GPU to the screen?
}
}Is my assumption correct ?
If yes, how do I exactly do the rendering part (code example would be highly appreciated) ? -
ffmpeg's segment_atclocktime cuts at inaccurate times for audio
3 mai 2023, par Ross RichardsonI am using ffmpeg's segment format to save files of an AAC stream to disk in hourly segments.
The segmenting works well, but the files are segmented/cut at different times in the clock each hour using
segment_atclocktime


I would like each to be exactly on the hour, e.g. 12:00:00, 13:00:00 etc. Or at least, beginning after the hour and not before, e.g. 12:00:00, 13:00:01, 14:00:00 etc.


I am using
ffmpeg-python
to process the AAC stream and send to two outputs : stdout and these segments.
Here's the code :

out1 = ffmpeg.input(stream, loglevel="panic").output("pipe:",
 format="s16le", 
 acodec="pcm_s16le", 
 ac="1", 
 ar="16000")

out2 = ffmpeg.input(stream, loglevel="info").output("rec/%Y-%m-%d-%H%M%S.aac",
 acodec="copy",
 format="segment",
 segment_time="3600",
 segment_atclocktime="1",
 reset_timestamps="1",
 strftime="1")
 
ffmpeg.merge_outputs(out1, out2)
 .run_async(pipe_stdout=True, overwrite_output=True)



Most files are produced at the desired time : 05:00:00, 06:00:00, 07:00:00, but one or two each day start at 08:59:59 (where 09:00:00 would be desired), or even 16:00:24.


I understand the segment needs to begin on a audio sample so it can't be perfect to the hour, but wondering how I can make it more consistent. Ideally, each hour's recording would begin at 00:00 or later, and not begin before the hour.


I have tried using
min_seg_duration 3600
,reset_timestamps 1

I am not sure how exactly to usesegment_clocktime_wrap_duration
for audio, or whethersegment_time_delta
applies to audio.

I'd appreciate any advice or understanding of how
segment_atclocktime
works with audio, as much on the internet seems video-focused.