Recherche avancée

Médias (2)

Mot : - Tags -/media

Autres articles (93)

  • 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 (...)

  • Le plugin : Gestion de la mutualisation

    2 mars 2010, par

    Le plugin de Gestion de mutualisation permet de gérer les différents canaux de mediaspip depuis un site maître. Il a pour but de fournir une solution pure SPIP afin de remplacer cette ancienne solution.
    Installation basique
    On installe les fichiers de SPIP sur le serveur.
    On ajoute ensuite le plugin "mutualisation" à la racine du site comme décrit ici.
    On customise le fichier mes_options.php central comme on le souhaite. Voilà pour l’exemple celui de la plateforme mediaspip.net :
    < ?php (...)

  • Gestion de la ferme

    2 mars 2010, par

    La ferme est gérée dans son ensemble par des "super admins".
    Certains réglages peuvent être fais afin de réguler les besoins des différents canaux.
    Dans un premier temps il utilise le plugin "Gestion de mutualisation"

Sur d’autres sites (10948)

  • ffmpeg : init filtergraphs only after we have a frame on each input

    27 mai 2016, par Anton Khirnov
    ffmpeg : init filtergraphs only after we have a frame on each input
    

    This makes sure the actual stream parameters are used, which is
    important mainly for hardware decoding+filtering cases, which would
    previously require various weird workarounds to handle the fact that a
    fake software graph has to be constructed, but never used.
    This should also improve behaviour in rare cases where
    avformat_find_stream_info() does not provide accurate information.

    This merges Libav commit a3a0230. It was previously skipped.

    The code in flush_encoders() which sets up a "fake" format wasn’t in
    Libav. I’m not sure if it’s a good idea, but it tends to give
    behavior closer to the old one in certain corner cases.

    The vp8-size-change gives different result, because now the size of
    the first frame is used. libavformat reported the size of the largest
    frame for some reason.

    The exr tests now use the sample aspect ratio of the first frame. For
    some reason libavformat determines 0/1 as aspect ratio, while the
    decoder returns the correct one.

    The ffm and mxf tests change the field_order values. I’m assuming
    another libavformat/decoding mismatch.

    Signed-off-by : wm4 <nfxjfg@googlemail.com>

    • [DH] ffmpeg.c
    • [DH] ffmpeg.h
    • [DH] ffmpeg_cuvid.c
    • [DH] ffmpeg_filter.c
    • [DH] ffmpeg_opt.c
    • [DH] ffmpeg_qsv.c
    • [DH] tests/ref/fate/exr-rgb-scanline-pxr24-half-uint32-13x9
    • [DH] tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l1
    • [DH] tests/ref/fate/exr-rgba-scanline-float-half-b44-12x8-l2
    • [DH] tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l1
    • [DH] tests/ref/fate/exr-rgba-scanline-float-half-b44-13x9-l2
    • [DH] tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l1
    • [DH] tests/ref/fate/exr-rgba-scanline-float-half-b44a-12x8-l2
    • [DH] tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l1
    • [DH] tests/ref/fate/exr-rgba-scanline-float-half-b44a-13x9-l2
    • [DH] tests/ref/fate/vp8-size-change
    • [DH] tests/ref/lavf/ffm
    • [DH] tests/ref/lavf/mxf
  • File encoded as FFV1 with ffmpeg is unplayable

    18 novembre 2016, par Ali Alidoust

    I’m using the following code to encode a series of frames into an mkv or avi file with FFV1 encoding :

    HRESULT Session::createContext(LPCSTR filepath, UINT width, UINT height, UINT fps_num, UINT fps_den) {
       LOG(filepath);

       this->codec = avcodec_find_encoder(AV_CODEC_ID_FFV1);
       RET_IF_NULL(this->codec, "Could not create codec", E_FAIL);

       this->oformat = av_guess_format(NULL, filepath, NULL);
       RET_IF_NULL(this->oformat, "Could not create format", E_FAIL);
       this->oformat->video_codec = AV_CODEC_ID_FFV1;
       this->width = width;
       this->height = height;
       this->context = avcodec_alloc_context3(this->codec);
       RET_IF_NULL(this->context, "Could not allocate context for the codec", E_FAIL);

       this->context->codec = this->codec;
       this->context->codec_id = AV_CODEC_ID_FFV1;
       this->context->codec_type = AVMEDIA_TYPE_VIDEO;

       this->context->pix_fmt = AV_PIX_FMT_YUV420P;
       this->context->width = this->width;
       this->context->height = this->height;
       this->context->time_base.num = fps_num;
       this->context->time_base.den = fps_den;

       this->context->gop_size = 1;

       av_opt_set_int(this->context->priv_data, "coder", 0, 0);
       av_opt_set_int(this->context->priv_data, "context", 1, 0);
       av_opt_set_int(this->context->priv_data, "slicecrc", 1, 0);

       avformat_alloc_output_context2(&amp;fmtContext, NULL, NULL, filepath);

       this->fmtContext->oformat = this->oformat;
       this->fmtContext->video_codec_id = AV_CODEC_ID_FFV1;

       this->stream = avformat_new_stream(this->fmtContext, this->codec);
       RET_IF_NULL(this->fmtContext, "Could not create new stream", E_FAIL);
       avcodec_parameters_from_context(this->stream->codecpar, this->context);
       this->stream->codecpar->level = 3;

       /*if (this->fmtContext->oformat->flags &amp; AVFMT_GLOBALHEADER)
       {*/
           this->context->flags |= CODEC_FLAG_GLOBAL_HEADER;
       /*}*/

       RET_IF_FAILED_AV(avcodec_open2(this->context, this->codec, NULL), "Could not open codec", E_FAIL);
       RET_IF_FAILED_AV(avio_open(&amp;this->fmtContext->pb, filepath, AVIO_FLAG_READ_WRITE), "Could not open output file", E_FAIL);
       RET_IF_NULL(this->fmtContext->pb, "Could not open output file", E_FAIL);
       RET_IF_FAILED_AV(avformat_write_header(this->fmtContext, NULL), "Could not write header", E_FAIL);

       frame = av_frame_alloc();
       RET_IF_NULL(frame, "Could not allocate frame", E_FAIL);
       frame->format = this->context->pix_fmt;
       frame->width = width;
       frame->height = height;
       // RET_IF_FAILED(av_image_alloc(frame->data, frame->linesize, context->width, context->height, context->pix_fmt, 32), "Could not allocate image", E_FAIL);
       return S_OK;
    }

    HRESULT Session::writeFrame(IMFSample * pSample) {
       IMFMediaBuffer *mediaBuffer = NULL;
       BYTE *pData = NULL;
       DWORD length;

       RET_IF_FAILED(pSample->ConvertToContiguousBuffer(&amp;mediaBuffer), "Could not convert IMFSample to contagiuous buffer", E_FAIL);
       RET_IF_FAILED(mediaBuffer->GetCurrentLength(&amp;length), "Could not get buffer length", E_FAIL);
       RET_IF_FAILED(mediaBuffer->Lock(&amp;pData, NULL, NULL), "Could not lock the buffer", E_FAIL);
       RET_IF_FAILED(av_image_fill_arrays(frame->data, frame->linesize, pData, AV_PIX_FMT_YUV420P, this->width, this->height, 1), "Could not fill the frame with data from the buffer", E_FAIL);
       LOG_IF_FAILED(mediaBuffer->Unlock(), "Could not unlock the buffer");

       frame->pts = this->pts++;

       AVPacket pkt;

       av_init_packet(&amp;pkt);
       pkt.data = NULL;
       pkt.size = 0;

       RET_IF_FAILED_AV(avcodec_send_frame(this->context, frame), "Could not send the frame to the encoder", E_FAIL);
       if (SUCCEEDED(avcodec_receive_packet(this->context, &amp;pkt))) {
           RET_IF_FAILED_AV(av_interleaved_write_frame(this->fmtContext, &amp;pkt), "Could not write the received packet.", E_FAIL);
       }

       av_packet_unref(&amp;pkt);

       return S_OK;
    }

    HRESULT Session::endSession() {
       LOG("Ending session...");
       LOG("Closing files...");
       av_write_trailer(this->fmtContext);
       avio_close(this->fmtContext->pb);
       avcodec_close(this->context);
       av_free(this->context);
       //fclose(this->file);
       LOG("Done.");
       return S_OK;
    }

    The problem is that the generated file is not playable in either VLC or MPC-HC. However, MPC-HC reports following info in file properties :

    General
    Unique ID                      : 202978442142665779317960161865934977227 (0x98B439D9BE859109BD5EC00A62A238CB)
    Complete name                  : T:\Test.mkv
    Format                         : Matroska
    Format version                 : Version 4 / Version 2
    File size                      : 24.6 MiB
    Duration                       : 147ms
    Overall bit rate               : 1 401 Mbps
    Writing application            : Lavf57.57.100
    Writing library                : Lavf57.57.100

    Video
    ID                             : 1
    Format                         : FFV1
    Format version                 : Version 0
    Codec ID                       : V_MS/VFW/FOURCC / FFV1
    Duration                       : 147ms
    Width                          : 1 280 pixels
    Height                         : 720 pixels
    Display aspect ratio           : 16:9
    Frame rate mode                : Constant
    Frame rate                     : 1 000.000 fps
    Color space                    : YUV
    Chroma subsampling             : 4:2:0
    Bit depth                      : 8 bits
    Compression mode               : Lossless
    Default                        : Yes
    Forced                         : No
    DURATION                       : 00:00:00.147000000
    coder_type                     : Golomb Rice

    Something to note is that it reports 1000 FPS which is weird since I’ve set AVCodecContext::time_base in the code.

  • Creating HLS stream from webm 10sec chunks

    23 avril 2021, par pawelm

    I want to make some live streaming functionality. I've got a page, where JS catches camera and sends about 10sec chunks to PHP script. It uses mediaDevices.getUserMedia(). Then my PHP script catches these chunks and save them as .webm. Next step is converting .webm chunks to .ts files and finally creating .m3u8 playlist file. Then .m3u8 playlist file is linked to video-js player with hls extension on watching page.

    &#xA;

    .ts and .m3u8 files generating works well - when I start recording and finish it ex. after 30 - 40 secs, .m3u8 ends up with '#EXT-X-ENDLIST' and JS HLS player successfully plays the whole recorded video. Problems appear in two situations :

    &#xA;

      &#xA;
    1. When stream recording is in progress, .ts files are being generated and .m3u8 file is being constantly updated with every next .ts - but when I try to play the stream via HLS player it plays the first chunk and then stops with loading icon. I can see in browser console that it downloads next .ts frames and updates the .m3u8 file, but player is freezing with loading icon.
    2. &#xA;

    3. When the stream is long, for example has 20-30 .ts files (few minutes) and I try to play it via HLS player - it tries to start from n chunk to present live video, not past fragments. I can see in browser console, that it starts downloading from ex. 10. .ts file or later, not the first one. But in player the result is black screen - it doesn't start playing.
    4. &#xA;

    &#xA;

    I think that problem is in converting webm to ts - there must be some options which I don't use properly or that I don't know about. Or maybe something is wrong with created .m3u8 file, this is my code (not optimized, firstly I want it start working) :

    &#xA;

    // get params - chunk number and stream identifier&#xA;$prefix = $_GET[&#x27;n&#x27;];&#xA;$num = $_GET[&#x27;c&#x27;];&#xA;$isFirst = false;&#xA;$isLast = isset($_GET[&#x27;f&#x27;]) &amp;&amp; $_GET[&#x27;f&#x27;];&#xA;&#xA;if(str_replace(&#x27;0&#x27;, &#x27;&#x27;, $num) == &#x27;&#x27;) {&#xA;    mkdir(&#x27;videos/&#x27;.$prefix);&#xA;    $isFirst = true;&#xA;}&#xA;&#xA;$fp = &#x27;videos\\&#x27;.$prefix.&#x27;\\&#x27;.$num.&#x27;.webm&#x27;;&#xA;$msg = &#x27;got &#x27;.$fp;&#xA;&#xA;$data = file_get_contents(&#x27;php://input&#x27;);&#xA;file_put_contents($fp, $data);&#xA;&#xA;// we determine exact chunk length&#xA;$detailsTxt = &#x27;videos\\&#x27;.$prefix.&#x27;\\&#x27;.$num.&#x27;.txt&#x27;;&#xA;exec("ffmpeg -i .\\$fp -f null - > .\\$detailsTxt 2>&amp;1");&#xA;&#xA;preg_match(&#x27;/(\d{2}:\d{2}:(\d{2}.\d{2}))/&#x27;, file_get_contents($detailsTxt), $matches);&#xA;$matches = array_filter($matches);&#xA;$duration = (float)trim($matches[2], &#x27;0&#x27;);&#xA;&#xA;$durationTxt = &#x27;videos\\&#x27;.$prefix.&#x27;\\&#x27;.$num.&#x27;_dur.txt&#x27;;&#xA;file_put_contents($durationTxt, $duration);&#xA;&#xA;// ts convertion&#xA;&#xA;// counting start timestamp&#xA;$FPS = 25;&#xA;$t0 = 0;&#xA;$cursorTxt = &#x27;videos\\&#x27;.$prefix.&#x27;\\cursor.txt&#x27;;&#xA;if(file_exists($cursorTxt)) $t0 = (float)file_get_contents($cursorTxt);&#xA;file_put_contents($cursorTxt, $t0 &#x2B; $duration /*&#x2B; 1/$FPS*/);&#xA;&#xA;$fp2 = str_replace(&#x27;.webm&#x27;, &#x27;.ts&#x27;, $fp);&#xA;$details2Txt = &#x27;videos\\&#x27;.$prefix.&#x27;\\&#x27;.$num.&#x27;_conv.txt&#x27;;&#xA;&#xA;$convertCommand = [&#xA;    &#x27;ffmpeg&#x27;,&#xA;    &#x27;-v&#x27;, &#x27;quiet&#x27;,&#xA;    &#x27;-loglevel&#x27;, &#x27;error&#x27;,&#xA;    &#x27;-i&#x27;, ".\\$fp",&#xA;    &#x27;-vcodec&#x27;, &#x27;libx264&#x27;,&#xA;    &#x27;-acodec&#x27;, &#x27;aac&#x27;,&#xA;    &#x27;-r&#x27;, $FPS,&#xA;    &#x27;-profile:v&#x27;, &#x27;baseline&#x27;,&#xA;    &#x27;-b:v&#x27;, &#x27;800k&#x27;,&#xA;    &#x27;-b:a&#x27;, &#x27;48k&#x27;,&#xA;    &#x27;-f&#x27;, &#x27;mpegts&#x27;,&#xA;    &#x27;-strict&#x27;, &#x27;experimental&#x27;,&#xA;    &#x27;-mpegts_copyts&#x27;, &#x27;1&#x27;,&#xA;    &#x27;-filter:v&#x27;, &#x27;setpts=PTS&#x2B;&#x27; . $t0 . &#x27;/TB&#x27;, // $t0&#xA;    &#x27;-y&#x27;,&#xA;    ".\\$fp2",&#xA;    "> .\\$details2Txt 2>&amp;1"&#xA;];&#xA;&#xA;exec(implode(" ", $convertCommand));&#xA;&#xA;// generating m3u8 file&#xA;&#xA;// counting max duration&#xA;$maxDuration = $duration;&#xA;$durationTxt = &#x27;videos\\&#x27;.$prefix.&#x27;\\duration.txt&#x27;;&#xA;if(file_exists($durationTxt)) {&#xA;    $tempDuration = (float)file_get_contents($durationTxt);&#xA;    if($tempDuration > $maxDuration) $maxDuration = $tempDuration;&#xA;    else file_put_contents($durationTxt, $maxDuration);&#xA;}else file_put_contents($durationTxt, $maxDuration);&#xA;&#xA;file_put_contents($cursorTxt, $t0 &#x2B; $duration);&#xA;&#xA;$m3u8File = &#x27;videos\\&#x27;.$prefix.&#x27;\\playlist.m3u8&#x27;;&#xA;$m3u8Content = [];&#xA;&#xA;$counter = 0;&#xA;do {&#xA;    $paddedCounter = str_pad($counter, 5, &#x27;0&#x27;, STR_PAD_LEFT);&#xA;    $chunkFile = &#x27;videos\\&#x27;.$prefix.&#x27;\\&#x27;.$paddedCounter.&#x27;.ts&#x27;;&#xA;    if(!file_exists($chunkFile)) break;&#xA;    $counter&#x2B;&#x2B;;&#xA;}while(true);&#xA;&#xA;$m3u8Content[] = "#EXTM3U";&#xA;$m3u8Content[] = "#EXT-X-VERSION:3";&#xA;$m3u8Content[] = "#EXT-X-MEDIA-SEQUENCE:$counter";&#xA;$m3u8Content[] = "#EXT-X-ALLOW-CACHE:YES";&#xA;$m3u8Content[] = "#EXT-X-TARGETDURATION:".ceil($maxDuration);&#xA;$m3u8Content[] = "";&#xA;&#xA;$counter = 0;&#xA;do {&#xA;    $paddedCounter = str_pad($counter, 5, &#x27;0&#x27;, STR_PAD_LEFT);&#xA;    $chunkFile = &#x27;videos\\&#x27;.$prefix.&#x27;\\&#x27;.$paddedCounter.&#x27;.ts&#x27;;&#xA;    if(!file_exists($chunkFile)) break;&#xA;&#xA;    $durationTxt = &#x27;videos\\&#x27;.$prefix.&#x27;\\&#x27;.$paddedCounter.&#x27;_dur.txt&#x27;;&#xA;    $duration = (float)file_get_contents($durationTxt);&#xA;&#xA;    $m3u8Content[] = "#EXTINF:$duration,";&#xA;    $m3u8Content[] = "$paddedCounter.ts";&#xA;&#xA;    $counter&#x2B;&#x2B;;&#xA;}while(true);&#xA;&#xA;if($isLast) $m3u8Content[] = "#EXT-X-ENDLIST";&#xA;$m3u8Content[] = "";&#xA;&#xA;file_put_contents($m3u8File, implode("\n", $m3u8Content));&#xA;

    &#xA;

    EDIT : I've just discovered, that everything works well when I disable audio stream recording in getUserMedia - so when I record only video stream. That's weird - like some synchronization between audio and video streams problem.

    &#xA;