Recherche avancée

Médias (1)

Mot : - Tags -/vidéo

Autres articles (58)

  • Pas question de marché, de cloud etc...

    10 avril 2011

    Le vocabulaire utilisé sur ce site essaie d’éviter toute référence à la mode qui fleurit allègrement
    sur le web 2.0 et dans les entreprises qui en vivent.
    Vous êtes donc invité à bannir l’utilisation des termes "Brand", "Cloud", "Marché" etc...
    Notre motivation est avant tout de créer un outil simple, accessible à pour tout le monde, favorisant
    le partage de créations sur Internet et permettant aux auteurs de garder une autonomie optimale.
    Aucun "contrat Gold ou Premium" n’est donc prévu, aucun (...)

  • Les tâches Cron régulières de la ferme

    1er décembre 2010, par

    La gestion de la ferme passe par l’exécution à intervalle régulier de plusieurs tâches répétitives dites Cron.
    Le super Cron (gestion_mutu_super_cron)
    Cette tâche, planifiée chaque minute, a pour simple effet d’appeler le Cron de l’ensemble des instances de la mutualisation régulièrement. Couplée avec un Cron système sur le site central de la mutualisation, cela permet de simplement générer des visites régulières sur les différents sites et éviter que les tâches des sites peu visités soient trop (...)

  • Amélioration de la version de base

    13 septembre 2013

    Jolie sélection multiple
    Le plugin Chosen permet d’améliorer l’ergonomie des champs de sélection multiple. Voir les deux images suivantes pour comparer.
    Il suffit pour cela d’activer le plugin Chosen (Configuration générale du site > Gestion des plugins), puis de configurer le plugin (Les squelettes > Chosen) en activant l’utilisation de Chosen dans le site public et en spécifiant les éléments de formulaires à améliorer, par exemple select[multiple] pour les listes à sélection multiple (...)

Sur d’autres sites (6564)

  • Transcode HLS Segments individually using FFMPEG

    27 mai 2013, par rayh

    I am recording a continuous, live stream to a high-bitrate HLS stream. I then want to asynchronously transcode this to different formats/bitrates. I have this working, mostly, except audio artefacts are appearing between each segment (gaps and pops).

    Here is an example ffmpeg command line :

    ffmpeg -threads 1 -nostdin -loglevel verbose \
      -nostdin -y -i input.ts -c:a libfdk_aac \
      -ac 2 -b:a 64k -y -metadata -vn output.ts

    Inspecting an example sound file shows that there is a gap at the end of the audio :

    End

    And the start of the file looks suspiciously attenuated (although this may not be an issue) :

    Start

    My suspicion is that these artefacts are happening because transcoding are occurring without the context of the stream as a whole.

    Any ideas on how to convince FFMPEG to produce audio that will fit back into a HLS stream ?

    ** UPDATE 1 **

    Here are the start/end of the original segment. As you can see, the start still appears the same, but the end is cleanly ended at 30s. I expect some degree of padding with lossy encoding, but I there is some way that HLS manages to do gapless playback (is this related to iTunes method with custom metadata ?)

    Original Start
    Original End

    ** UPDATED 2 **

    So, I converted both the original (128k aac in MPEG2 TS) and the transcoded (64k aac in aac/adts container) to WAV and put the two side-by-side. This is the result :

    Side-by-side start
    Side-by-side end

    I'm not sure if this is representative of how a client will play it back, but it seems a bit odd that decoding the transcoded one introduces a gap at the start and makes the segment longer. Given they are both lossy encoding, I would have expected padding to be equally present in both (if at all).

    ** UPDATE 3 **

    According to http://en.wikipedia.org/wiki/Gapless_playback - Only a handful of encoders support gapless - for MP3, I've switched to lame in ffmpeg, and the problem, so far, appears to have gone.

    For AAC (see http://en.wikipedia.org/wiki/FAAC), I have tried libfaac (as opposed to libfdk_aac) and it also seems to produce gapless audio. However, the quality of the latter isn't that great and I'd rather use libfdk_aac is possible.

  • Révision 93109 : Compat PHP7 (peut être pas encore suffisant).

    23 novembre 2015, par marcimat@rezo.net

    La structure foreach change de comportement et s’applique par défaut sur une copie du tableau passé.
    Si on modifie le tableau dans le foreach… bien celui d’origine n’est pas affecté. Pour retrouver
    le comportement d’avant dans ces cas là, il faut passer la valeur par référence.

    cf.
    https://wiki.php.net/rfc/php7_foreach
    http://php.net/manual/fr/migration70.incompatible.php

  • Record rtsp stream with ffmpeg in iOS

    27 janvier 2017, par Wei Wen Hsiao

    I’ve followed iFrameExtractor to successfully stream rtsp in my swift project. In this project, it also has recording function. It basically use avformat_write_header
    , av_interleaved_write_frame and av_write_trailer to save the rtsp source into mp4 file.

    When I used this project in my device, the rtsp streaming works fine, but recording function will always generate a blank mp4 file with no image and sound.

    Could anyone tell me what step that I miss ?

    I’m using iPhone5 with iOS 9.1 and XCode 7.1.1.
    The ffmpeg is 2.8.3 version and followed the compile instruction by CompilationGuide – FFmpeg

    Following is the sample code in this project

    The function that generate every frame :

    -(BOOL)stepFrame {
    // AVPacket packet;
    int frameFinished=0;
    static bool bFirstIFrame=false;
    static int64_t vPTS=0, vDTS=0, vAudioPTS=0, vAudioDTS=0;

    while(!frameFinished && av_read_frame(pFormatCtx, &packet)>=0) {
       // Is this a packet from the video stream?
       if(packet.stream_index==videoStream) {

           // 20130525 albert.liao modified start

           // Initialize a new format context for writing file
           if(veVideoRecordState!=eH264RecIdle)
           {
               switch(veVideoRecordState)
               {
                   case eH264RecInit:
                   {                        
                       if ( !pFormatCtx_Record )
                       {
                           int bFlag = 0;
                           //NSString *videoPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/test.mp4"];
                           NSString *videoPath = @"/Users/liaokuohsun/iFrameTest.mp4";

                           const char *file = [videoPath UTF8String];
                           pFormatCtx_Record = avformat_alloc_context();
                           bFlag = h264_file_create(file, pFormatCtx_Record, pCodecCtx, pAudioCodecCtx,/*fps*/0.0, packet.data, packet.size );

                           if(bFlag==true)
                           {
                               veVideoRecordState = eH264RecActive;
                               fprintf(stderr, "h264_file_create success\n");                                
                           }
                           else
                           {
                               veVideoRecordState = eH264RecIdle;
                               fprintf(stderr, "h264_file_create error\n");
                           }
                       }
                   }
                   //break;

                   case eH264RecActive:
                   {
                       if((bFirstIFrame==false) &&(packet.flags&AV_PKT_FLAG_KEY)==AV_PKT_FLAG_KEY)
                       {
                           bFirstIFrame=true;
                           vPTS = packet.pts ;
                           vDTS = packet.dts ;
    #if 0
                           NSRunLoop *pRunLoop = [NSRunLoop currentRunLoop];
                           [pRunLoop addTimer:RecordingTimer forMode:NSDefaultRunLoopMode];
    #else
                           [NSTimer scheduledTimerWithTimeInterval:5.0//2.0
                                                            target:self
                                                          selector:@selector(StopRecording:)
                                                          userInfo:nil
                                                           repeats:NO];
    #endif
                       }

                       // Record audio when 1st i-Frame is obtained
                       if(bFirstIFrame==true)
                       {
                           if ( pFormatCtx_Record )
                           {
    #if PTS_DTS_IS_CORRECT==1
                               packet.pts = packet.pts - vPTS;
                               packet.dts = packet.dts - vDTS;

    #endif
                                   h264_file_write_frame( pFormatCtx_Record, packet.stream_index, packet.data, packet.size, packet.dts, packet.pts);

                           }
                           else
                           {
                               NSLog(@"pFormatCtx_Record no exist");
                           }
                       }
                   }
                   break;

                   case eH264RecClose:
                   {
                       if ( pFormatCtx_Record )
                       {
                           h264_file_close(pFormatCtx_Record);
    #if 0
                           // 20130607 Test
                           dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
                           {
                               ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init];
                               NSString *filePathString = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/test.mp4"];
                               NSURL *filePathURL = [NSURL fileURLWithPath:filePathString isDirectory:NO];
                               if(1)// ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:filePathURL])
                               {
                                   [library writeVideoAtPathToSavedPhotosAlbum:filePathURL completionBlock:^(NSURL *assetURL, NSError *error){
                                       if (error) {
                                           // TODO: error handling
                                           NSLog(@"writeVideoAtPathToSavedPhotosAlbum error");
                                       } else {
                                           // TODO: success handling
                                           NSLog(@"writeVideoAtPathToSavedPhotosAlbum success");
                                       }
                                   }];
                               }
                               [library release];
                           });
    #endif
                           vPTS = 0;
                           vDTS = 0;
                           vAudioPTS = 0;
                           vAudioDTS = 0;
                           pFormatCtx_Record = NULL;
                           NSLog(@"h264_file_close() is finished");
                       }
                       else
                       {
                           NSLog(@"fc no exist");
                       }
                       bFirstIFrame = false;
                       veVideoRecordState = eH264RecIdle;

                   }
                   break;

                   default:
                       if ( pFormatCtx_Record )
                       {
                           h264_file_close(pFormatCtx_Record);
                           pFormatCtx_Record = NULL;
                       }
                       NSLog(@"[ERROR] unexpected veVideoRecordState!!");
                       veVideoRecordState = eH264RecIdle;
                       break;
               }
           }

           // Decode video frame
           avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
       }
       else if(packet.stream_index==audioStream)
       {
           // 20131024 albert.liao modfied start
           static int vPktCount=0;
           BOOL bIsAACADTS = FALSE;
           int ret = 0;

           if(aPlayer.vAACType == eAAC_UNDEFINED)
           {
               tAACADTSHeaderInfo vxAACADTSHeaderInfo = {0};
               bIsAACADTS = [AudioUtilities parseAACADTSHeader:(uint8_t *)packet.data ToHeader:&vxAACADTSHeaderInfo];
           }

           @synchronized(aPlayer)
           {
               if(aPlayer==nil)
               {
                   aPlayer = [[AudioPlayer alloc]initAudio:nil withCodecCtx:(AVCodecContext *) pAudioCodecCtx];
                   NSLog(@"aPlayer initAudio");

                   if(bIsAACADTS)
                   {
                       aPlayer.vAACType = eAAC_ADTS;
                       //NSLog(@"is ADTS AAC");
                   }
               }
               else
               {
                   if(vPktCount<5) // The voice is listened once image is rendered
                   {
                       vPktCount++;
                   }
                   else
                   {
                       if([aPlayer getStatus]!=eAudioRunning)
                       {
                           dispatch_async(dispatch_get_main_queue(), ^(void) {
                               @synchronized(aPlayer)
                               {
                                   NSLog(@"aPlayer start play");
                                   [aPlayer Play];
                               }

                           });
                       }
                   }
               }
           };

           @synchronized(aPlayer)
           {
               int ret = 0;

               ret = [aPlayer putAVPacket:&packet];
               if(ret <= 0)
                   NSLog(@"Put Audio Packet Error!!");

           }

           // 20131024 albert.liao modfied end

           if(bFirstIFrame==true)
           {
               switch(veVideoRecordState)
               {
                   case eH264RecActive:
                   {
                       if ( pFormatCtx_Record )
                       {
                           h264_file_write_audio_frame(pFormatCtx_Record, pAudioCodecCtx, packet.stream_index, packet.data, packet.size, packet.dts, packet.pts);

                       }
                       else
                       {
                           NSLog(@"pFormatCtx_Record no exist");
                       }
                   }
               }
           }
       }
       else
       {
           //fprintf(stderr, "packet len=%d, Byte=%02X%02X%02X%02X%02X\n",\
                   packet.size, packet.data[0],packet.data[1],packet.data[2],packet.data[3], packet.data[4]);
       }
       // 20130525 albert.liao modified end
    }
    return frameFinished!=0;
    }

    avformat_write_header :

    int h264_file_create(const char *pFilePath, AVFormatContext *fc, AVCodecContext *pCodecCtx,AVCodecContext *pAudioCodecCtx, double fps, void *p, int len )
    {
    int vRet=0;
    AVOutputFormat *of=NULL;
    AVStream *pst=NULL;
    AVCodecContext *pcc=NULL, *pAudioOutputCodecContext=NULL;

    avcodec_register_all();
    av_register_all();
    av_log_set_level(AV_LOG_VERBOSE);

    if(!pFilePath)
    {
       fprintf(stderr, "FilePath no exist");
       return -1;
    }

    if(!fc)
    {
       fprintf(stderr, "AVFormatContext no exist");
       return -1;
    }
    fprintf(stderr, "file=%s\n",pFilePath);

    // Create container
    of = av_guess_format( 0, pFilePath, 0 );
    fc->oformat = of;
    strcpy( fc->filename, pFilePath );

    // Add video stream
    pst = avformat_new_stream( fc, 0 );
    vVideoStreamIdx = pst->index;
    fprintf(stderr,"Video Stream:%d",vVideoStreamIdx);

    pcc = pst->codec;
    avcodec_get_context_defaults3( pcc, AVMEDIA_TYPE_VIDEO );

    // Save the stream as origin setting without convert
    pcc->codec_type = pCodecCtx->codec_type;
    pcc->codec_id = pCodecCtx->codec_id;
    pcc->bit_rate = pCodecCtx->bit_rate;
    pcc->width = pCodecCtx->width;
    pcc->height = pCodecCtx->height;

    if(fps==0)
    {
       double fps=0.0;
       AVRational pTimeBase;
       pTimeBase.num = pCodecCtx->time_base.num;
       pTimeBase.den = pCodecCtx->time_base.den;
       fps = 1.0/ av_q2d(pCodecCtx->time_base)/ FFMAX(pCodecCtx->ticks_per_frame, 1);
       fprintf(stderr,"fps_method(tbc): 1/av_q2d()=%g",fps);
       pcc->time_base.num = 1;
       pcc->time_base.den = fps;
    }
    else
    {
       pcc->time_base.num = 1;
       pcc->time_base.den = fps;
    }
    // reference ffmpeg\libavformat\utils.c

    // For SPS and PPS in avcC container
    pcc->extradata = malloc(sizeof(uint8_t)*pCodecCtx->extradata_size);
    memcpy(pcc->extradata, pCodecCtx->extradata, pCodecCtx->extradata_size);
    pcc->extradata_size = pCodecCtx->extradata_size;

    // For Audio stream
    if(pAudioCodecCtx)
    {
       AVCodec *pAudioCodec=NULL;
       AVStream *pst2=NULL;
       pAudioCodec = avcodec_find_encoder(AV_CODEC_ID_AAC);

       // Add audio stream
       pst2 = avformat_new_stream( fc, pAudioCodec );
       vAudioStreamIdx = pst2->index;
       pAudioOutputCodecContext = pst2->codec;
       avcodec_get_context_defaults3( pAudioOutputCodecContext, pAudioCodec );
       fprintf(stderr,"Audio Stream:%d",vAudioStreamIdx);
       fprintf(stderr,"pAudioCodecCtx->bits_per_coded_sample=%d",pAudioCodecCtx->bits_per_coded_sample);

       pAudioOutputCodecContext->codec_type = AVMEDIA_TYPE_AUDIO;
       pAudioOutputCodecContext->codec_id = AV_CODEC_ID_AAC;

       // Copy the codec attributes
       pAudioOutputCodecContext->channels = pAudioCodecCtx->channels;
       pAudioOutputCodecContext->channel_layout = pAudioCodecCtx->channel_layout;
       pAudioOutputCodecContext->sample_rate = pAudioCodecCtx->sample_rate;
       pAudioOutputCodecContext->bit_rate = 12000;//pAudioCodecCtx->sample_rate * pAudioCodecCtx->bits_per_coded_sample;
       pAudioOutputCodecContext->bits_per_coded_sample = pAudioCodecCtx->bits_per_coded_sample;
       pAudioOutputCodecContext->profile = pAudioCodecCtx->profile;
       //FF_PROFILE_AAC_LOW;
       // pAudioCodecCtx->bit_rate;

       // AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P
       //pAudioOutputCodecContext->sample_fmt = AV_SAMPLE_FMT_FLTP;//pAudioCodecCtx->sample_fmt;
       pAudioOutputCodecContext->sample_fmt = pAudioCodecCtx->sample_fmt;
       //pAudioOutputCodecContext->sample_fmt = AV_SAMPLE_FMT_U8;

       pAudioOutputCodecContext->sample_aspect_ratio = pAudioCodecCtx->sample_aspect_ratio;

       pAudioOutputCodecContext->time_base.num = pAudioCodecCtx->time_base.num;
       pAudioOutputCodecContext->time_base.den = pAudioCodecCtx->time_base.den;
       pAudioOutputCodecContext->ticks_per_frame = pAudioCodecCtx->ticks_per_frame;
       pAudioOutputCodecContext->frame_size = 1024;

       fprintf(stderr,"profile:%d, sample_rate:%d, channles:%d", pAudioOutputCodecContext->profile, pAudioOutputCodecContext->sample_rate, pAudioOutputCodecContext->channels);
       AVDictionary *opts = NULL;
       av_dict_set(&opts, "strict", "experimental", 0);

       if (avcodec_open2(pAudioOutputCodecContext, pAudioCodec, &opts) < 0) {
           fprintf(stderr, "\ncould not open codec\n");
       }

       av_dict_free(&opts);

    #if 0
       // For Audio, this part is no need
       if(pAudioCodecCtx->extradata_size!=0)
       {
           NSLog(@"extradata_size !=0");
           pAudioOutputCodecContext->extradata = malloc(sizeof(uint8_t)*pAudioCodecCtx->extradata_size);
           memcpy(pAudioOutputCodecContext->extradata, pAudioCodecCtx->extradata, pAudioCodecCtx->extradata_size);
           pAudioOutputCodecContext->extradata_size = pAudioCodecCtx->extradata_size;
       }
       else
       {
           // For WMA test only
           pAudioOutputCodecContext->extradata_size = 0;
           NSLog(@"extradata_size ==0");
       }
    #endif
    }

    if(fc->oformat->flags & AVFMT_GLOBALHEADER)
    {
       pcc->flags |= CODEC_FLAG_GLOBAL_HEADER;
       pAudioOutputCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }

    if ( !( fc->oformat->flags & AVFMT_NOFILE ) )
    {
       vRet = avio_open( &fc->pb, fc->filename, AVIO_FLAG_WRITE );
       if(vRet!=0)
       {
           fprintf(stderr,"avio_open(%s) error", fc->filename);
       }
    }

    // dump format in console
    av_dump_format(fc, 0, pFilePath, 1);

    vRet = avformat_write_header( fc, NULL );
    if(vRet==0)
       return 1;
    else
       return 0;
    }

    av_interleaved_write_frame :

    void h264_file_write_frame(AVFormatContext *fc, int vStreamIdx, const void* p, int len, int64_t dts, int64_t pts )
    {
       AVStream *pst = NULL;
       AVPacket pkt;

    if ( 0 > vVideoStreamIdx )
       return;

    // may be audio or video
    pst = fc->streams[ vStreamIdx ];

    // Init packet
    av_init_packet( &pkt );

    if(vStreamIdx ==vVideoStreamIdx)
    {
       pkt.flags |= ( 0 >= getVopType( p, len ) ) ? AV_PKT_FLAG_KEY : 0;
       //pkt.flags |= AV_PKT_FLAG_KEY;
       pkt.stream_index = pst->index;
       pkt.data = (uint8_t*)p;
       pkt.size = len;


       pkt.dts = AV_NOPTS_VALUE;
       pkt.pts = AV_NOPTS_VALUE;

       // TODO: mark or unmark the log
       //fprintf(stderr, "dts=%lld, pts=%lld\n",dts,pts);
       // av_write_frame( fc, &pkt );
    }
    av_interleaved_write_frame( fc, &pkt );
    }

    av_write_trailer :

    void h264_file_close(AVFormatContext *fc)
    {
    if ( !fc )
       return;

    av_write_trailer( fc );


    if ( fc->oformat && !( fc->oformat->flags & AVFMT_NOFILE ) && fc->pb )
       avio_close( fc->pb );

    av_free( fc );
    }

    Thanks.