Recherche avancée

Médias (2)

Mot : - Tags -/documentation

Autres articles (78)

  • Dépôt de média et thèmes par FTP

    31 mai 2013, par

    L’outil MédiaSPIP traite aussi les média transférés par la voie FTP. Si vous préférez déposer par cette voie, récupérez les identifiants d’accès vers votre site MédiaSPIP et utilisez votre client FTP favori.
    Vous trouverez dès le départ les dossiers suivants dans votre espace FTP : config/ : dossier de configuration du site IMG/ : dossier des média déjà traités et en ligne sur le site local/ : répertoire cache du site web themes/ : les thèmes ou les feuilles de style personnalisées tmp/ : dossier de travail (...)

  • Qualité du média après traitement

    21 juin 2013, par

    Le bon réglage du logiciel qui traite les média est important pour un équilibre entre les partis ( bande passante de l’hébergeur, qualité du média pour le rédacteur et le visiteur, accessibilité pour le visiteur ). Comment régler la qualité de son média ?
    Plus la qualité du média est importante, plus la bande passante sera utilisée. Le visiteur avec une connexion internet à petit débit devra attendre plus longtemps. Inversement plus, la qualité du média est pauvre et donc le média devient dégradé voire (...)

  • Le plugin : Podcasts.

    14 juillet 2010, par

    Le problème du podcasting est à nouveau un problème révélateur de la normalisation des transports de données sur Internet.
    Deux formats intéressants existent : Celui développé par Apple, très axé sur l’utilisation d’iTunes dont la SPEC est ici ; Le format "Media RSS Module" qui est plus "libre" notamment soutenu par Yahoo et le logiciel Miro ;
    Types de fichiers supportés dans les flux
    Le format d’Apple n’autorise que les formats suivants dans ses flux : .mp3 audio/mpeg .m4a audio/x-m4a .mp4 (...)

Sur d’autres sites (6466)

  • TS video copied to MP4, missing 3 first frames when programmatically read (ffmpeg bug)

    3 septembre 2023, par Vasilis Lemonidis

    Running :

    


    ffmpeg -i test.ts -fflags +genpts -c copy -y test.mp4


    


    for this test.ts, which has 30 frames, readable by opencv, I end up with 28 frames, out of which 27 are readable by opencv. More specifically :

    


    ffprobe -v error -select_streams v:0 -count_packets  -show_entries stream=nb_read_packets -of csv=p=0 tmp.ts 


    


    returns 30.

    


    ffprobe -v error -select_streams v:0 -count_packets     -show_entries stream=nb_read_packets -of csv=p=0 tmp.mp4


    


    returns 28.

    


    Using OpenCV in that manner

    


    cap = cv2.VideoCapture(tmp_path)
readMat = []
while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        readMat.append(frame)


    


    I get for the ts file 30 frames, while for the mp4 27 frames.

    


    Could someone explain why the discrepancies ? I get no error during the transformation from ts to mp4 :

    


    ffmpeg version N-111746-gd53acf452f Copyright (c) 2000-2023 the FFmpeg developers
  built with gcc 11.3.0 (GCC)
  configuration: --ld=g++ --bindir=/bin --extra-libs='-lpthread -lm' --pkg-config-flags=--static --enable-static --enable-gpl --enable-libaom --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libsvtav1 --enable-libdav1d --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree --enable-cuda-nvcc --enable-cuvid --enable-nvenc --enable-libnpp 
  libavutil      58. 16.101 / 58. 16.101
  libavcodec     60. 23.100 / 60. 23.100
  libavformat    60. 10.100 / 60. 10.100
  libavdevice    60.  2.101 / 60.  2.101
  libavfilter     9. 10.100 /  9. 10.100
  libswscale      7.  3.100 /  7.  3.100
  libswresample   4. 11.100 /  4. 11.100
  libpostproc    57.  2.100 / 57.  2.100
[mpegts @ 0x4237240] DTS discontinuity in stream 0: packet 5 with DTS 306003, packet 6 with DTS 396001
Input #0, mpegts, from 'tmp.ts':
  Duration: 00:00:21.33, start: 3.400000, bitrate: 15 kb/s
  Program 1 
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
  Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 300x300, 1 fps, 3 tbr, 90k tbn
Output #0, mp4, to 'test.mp4':
  Metadata:
    encoder         : Lavf60.10.100
  Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 300x300, q=2-31, 1 fps, 3 tbr, 90k tbn
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
[out#0/mp4 @ 0x423e280] video:25kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 4.192123%
frame=   30 fps=0.0 q=-1.0 Lsize=      26kB time=00:00:21.00 bitrate=  10.3kbits/s speed=1e+04x 


    


    Additional information

    


    The origin of the video I am processing comes from a continuous stitching operation of still images ts videos, produced by this class update method :

    


    import cv2
import os
import subprocess
from tempfile import NamedTemporaryFile
class VideoUpdater:
    def __init__(
        self, video_path: str, framerate: int, timePerFrame: Optional[int] = None
    ):
        """
        Video updater takes in a video path, and updates it using a supplied frame, based on a given framerate.
        Args:
            video_path: str: Specify the path to the video file
            framerate: int: Set the frame rate of the video
        """
        if not video_path.endswith(".mp4"):
            LOGGER.warning(
                f"File type {os.path.splitext(video_path)[1]} not supported for streaming, switching to ts"
            )
            video_path = os.path.splitext(video_path)[0] + ".mp4"

        self._ps = None
        self.env = {
            
        }
        self.ffmpeg = "/usr/bin/ffmpeg "

        self.video_path = video_path
        self.ts_path = video_path.replace(".mp4", ".ts")
        self.tfile = None
        self.framerate = framerate
        self._video = None
        self.last_frame = None
        self.curr_frame = None


    def update(self, frame: np.ndarray):
        if len(frame.shape) == 2:
            frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
        else:
            frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        self.writeFrame(frame)

    def writeFrame(self, frame: np.ndarray):
        """
        The writeFrame function takes a frame and writes it to the video file.
        Args:
            frame: np.ndarray: Write the frame to a temporary file
        """


        tImLFrame = NamedTemporaryFile(suffix=".png")
        tVidLFrame = NamedTemporaryFile(suffix=".ts")

        cv2.imwrite(tImLFrame.name, frame)
        ps = subprocess.Popen(
            self.ffmpeg
            + rf"-loop 1 -r {self.framerate} -i {tImLFrame.name} -t {self.framerate} -vcodec libx264 -pix_fmt yuv420p -y {tVidLFrame.name}",
            env=self.env,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        ps.communicate()
        if os.path.isfile(self.ts_path):
            # this does not work to watch, as timestamps are not updated
            ps = subprocess.Popen(
                self.ffmpeg
                + rf'-i "concat:{self.ts_path}|{tVidLFrame.name}" -c copy -y {self.ts_path.replace(".ts", ".bak.ts")}',
                env=self.env,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            ps.communicate()
            shutil.move(self.ts_path.replace(".ts", ".bak.ts"), self.ts_path)

        else:
            shutil.copyfile(tVidLFrame.name, self.ts_path)
        # fixing timestamps, we dont have to wait for this operation
        ps = subprocess.Popen(
            self.ffmpeg
            + rf"-i {self.ts_path} -fflags +genpts -c copy -y {self.video_path}",
            env=self.env,
            shell=True,
            # stdout=subprocess.PIPE,
            # stderr=subprocess.PIPE,
        )
        tImLFrame.close()
        tVidLFrame.close()


    


  • How can you combine multiple video files with FFMPEG and merging the audio track as well

    19 décembre 2023, par Codrut

    I'm trying to combine multiple MP4 files in Delphi with the FFMPEG video library. I have the headers unit with all the functions. All videos are MPEG-4, and so is the destination output file.

    


    I found this question on Stack Overflow asking the same question. To combine video files while keeping the audio and video tracks.
I have translated the answers to Delphi, and while the code is executed successfully, the output file is invalid and cannot be played.

    


    Here is my implementation :

    


    var&#xA;  Files: TArray<pansichar>;&#xA;  Output: PAnsiChar;&#xA;&#xA;  I, S: integer;&#xA;&#xA;  i_fmt_ctx: PAVFormatContext;&#xA;  i_video_stream: PAVStream;&#xA;  o_fmt_ctx: PAVFormatContext;&#xA;  o_video_stream: PAVStream;&#xA;&#xA;  P: PPAVStream;&#xA;begin&#xA;  SetLength(Files, 2);&#xA;  Files[0] := PAnsiChar(&#x27;.\Clips\file9.mp4&#x27;);&#xA;  Files[1] := PAnsiChar(&#x27;.\Clips\file10.mp4&#x27;);&#xA;  Output := &#x27;.\Output\out.mp4&#x27;;&#xA;&#xA;  avcodec_register_all();   &#xA;  av_register_all();&#xA;&#xA;  (* should set to NULL so that avformat_open_input() allocate a new one *)&#xA;  i_fmt_ctx := nil;&#xA;&#xA;  if avformat_open_input(@i_fmt_ctx, Files[0], nil, nil) &lt;> 0 then&#xA;    raise Exception.Create(&#x27;Could not open file&#x27;);&#xA;&#xA;  if avformat_find_stream_info(i_fmt_ctx, nil) &lt; 0 then&#xA;    raise Exception.Create(&#x27;Could not find stream info&#x27;);&#xA;                &#xA;  (* Find 1st video stream *)&#xA;  i_video_stream := nil;&#xA;  P := i_fmt_ctx.streams;&#xA;  for i := 0 to i_fmt_ctx.nb_streams-1 do begin&#xA;    if P^.codec.codec_type = AVMEDIA_TYPE_VIDEO then&#xA;      begin&#xA;        i_video_stream := P^;&#xA;        Break;&#xA;      end;&#xA;    Inc(P);&#xA;  end;&#xA;  if i_video_stream = nil then&#xA;    raise Exception.Create(&#x27;Could not find video stream&#x27;);&#xA;&#xA;  avformat_alloc_output_context2(@o_fmt_ctx, nil, nil, Output);&#xA;&#xA;  (*&#xA;  since all input files are supposed to be identical (framerate, dimension, color format, ...)&#xA;  we can safely set output codec values from first input file&#xA;  *)&#xA;  o_video_stream := avformat_new_stream(o_fmt_ctx, nil);&#xA;  &#xA;  var c: PAVCodecContext;&#xA;  c := o_video_stream.codec;&#xA;  c.bit_rate := 400000;&#xA;  c.codec_id := i_video_stream.codec.codec_id;&#xA;  c.codec_type := i_video_stream.codec.codec_type;&#xA;  c.time_base.num := i_video_stream.time_base.num;&#xA;  c.time_base.den := i_video_stream.time_base.den;&#xA;  //fprintf(stderr, "time_base.num = %d time_base.den = %d\n", c->time_base.num, c->time_base.den);&#xA;  c.width := i_video_stream.codec.width;&#xA;  c.height := i_video_stream.codec.height;&#xA;  c.pix_fmt := i_video_stream.codec.pix_fmt;&#xA;  //printf("%d %d %d", c->width, c->height, c->pix_fmt);&#xA;  c.flags := i_video_stream.codec.flags;&#xA;  c.flags := c.flags or CODEC_FLAG_GLOBAL_HEADER;&#xA;  c.me_range := i_video_stream.codec.me_range;&#xA;  c.max_qdiff := i_video_stream.codec.max_qdiff;&#xA;&#xA;  c.qmin := i_video_stream.codec.qmin;&#xA;  c.qmax := i_video_stream.codec.qmax;&#xA;&#xA;  c.qcompress := i_video_stream.codec.qcompress;&#xA;&#xA;  c.extradata := i_video_stream.codec.extradata;&#xA;  c.extradata_size := i_video_stream.codec.extradata_size;&#xA;&#xA;  avio_open(@o_fmt_ctx.pb, Output, AVIO_FLAG_WRITE);&#xA;&#xA;  (* yes! this is redundant *)&#xA;  avformat_close_input(@i_fmt_ctx);&#xA;&#xA;  avformat_write_header(o_fmt_ctx, nil);&#xA;&#xA;  var last_pts: integer; last_pts := 0;&#xA;  var last_dts: integer; last_dts := 0;&#xA;  for i := 1 to High(Files) do begin&#xA;    i_fmt_ctx := nil;&#xA;&#xA;    if avformat_open_input(@i_fmt_ctx, Files[i], nil, nil) &lt;> 0 then&#xA;      raise Exception.Create(&#x27;Could not open input file&#x27;);&#xA;&#xA;    if avformat_find_stream_info(i_fmt_ctx, nil) &lt; 0 then&#xA;      raise Exception.Create(&#x27;Could not find stream info&#x27;);&#xA;&#xA;    av_dump_format(i_fmt_ctx, 0, Files[i], 0);&#xA;    &#xA;    (* we only use first video stream of each input file *)&#xA;    i_video_stream := nil;&#xA;&#xA;    P := i_fmt_ctx.streams;&#xA;    for S := 0 to i_fmt_ctx.nb_streams-1 do&#xA;      begin&#xA;        if (P^.codec.codec_type = AVMEDIA_TYPE_VIDEO) then&#xA;          begin&#xA;            i_video_stream := P^;&#xA;            break;&#xA;          end;&#xA;        &#xA;        Inc(P);&#xA;      end;&#xA;&#xA;    if i_video_stream = nil then&#xA;      raise Exception.Create(&#x27;Could not find video stream&#x27;);&#xA;    &#xA;    var pts, dts: int64;&#xA;    pts := 0; dts := 0;&#xA;    while true do begin&#xA;      var i_pkt: TAVPacket;&#xA;      av_init_packet( @i_pkt );&#xA;      i_pkt.size := 0;&#xA;      i_pkt.data := nil;&#xA;&#xA;      if av_read_frame(i_fmt_ctx, @i_pkt) &lt; 0 then&#xA;        break;&#xA;      (*&#xA;        pts and dts should increase monotonically&#xA;        pts should be >= dts&#xA;      *)&#xA;      i_pkt.flags := i_pkt.flags or AV_PKT_FLAG_KEY;&#xA;      pts := i_pkt.pts;&#xA;      Inc(i_pkt.pts, last_pts);&#xA;      dts := i_pkt.dts;&#xA;      Inc(i_pkt.dts, last_dts);&#xA;      i_pkt.stream_index := 0;&#xA;&#xA;      // Write&#xA;      av_interleaved_write_frame(o_fmt_ctx, @i_pkt);&#xA;    end;&#xA;&#xA;    Inc(last_dts, dts);&#xA;    Inc(last_pts, pts);  &#xA;  &#xA;    avformat_close_input(@i_fmt_ctx)&#xA;  end;&#xA;&#xA;  av_write_trailer(o_fmt_ctx);&#xA;&#xA;  avcodec_close(o_fmt_ctx.streams^.codec);&#xA;  av_freep(&amp;o_fmt_ctx.streams^.codec);&#xA;  av_freep(&amp;o_fmt_ctx.streams);&#xA;&#xA;  avio_close(o_fmt_ctx.pb);&#xA;  av_free(o_fmt_ctx);&#xA;</pansichar>

    &#xA;

    Which is a translation of Михаил Чеботарев's answer.

    &#xA;

    Even if the code worked, I see no handling of the AVMEDIA_TYPE_AUDIO stream, which means this answer is 1/2 of the problem, since It only combines the video stream.

    &#xA;

    Another approach I tried was using the UBitmaps2Video FFMPEG implementation, which is successfully able to merge the video files, but only the video stream, no audio.

    &#xA;

    I tried manually converting the audio stream with the Bass Audio Library. It was able to read the audio and write It in a single WAV file, which then I converted to MP3. Finally muxing the combined video file and the MP3 file with MuxStreams2. Unfortunately, the audio and video do not align properly. I was unable to pinpoint the issue.

    &#xA;

    Currently, the only functional option is using the precompiled FFMPEG Executables and using ShellExecute with the according parameters to combine the videos.&#xA;This more exactly :

    &#xA;

    ffmpeg -f concat -safe 0 -i video-list.txt -c copy output.mp4&#xA;

    &#xA;

    But I would still rather use the FFMPEG headers in Delphi to combine the videos that way, as that gives the option for Progress indicatiors, more control of the playback and the ability to pause the thread at any point.

    &#xA;

    So, why does my implementation to merge video files not work. And what is a good method to include the audio stream as well ?

    &#xA;

  • Crash on ffmpeg avcodec_encode_video in a Console app [closed]

    11 janvier 2024, par Robel Sharma

    I want make an encoder which encode a raw image into h263 format.But after loading and initializing ffmpeg library I got crash on avcodec_encode_video for a demo image.

    &#xA;&#xA;

    int _tmain(int argc, _TCHAR* argv[]) {&#xA;    avcodec_register_all();&#xA;    AVCodec *codec;&#xA;    AVCodecContext *c= NULL;&#xA;    int i, ret, x, y, got_output;&#xA;    FILE *f;&#xA;    AVFrame *frame;&#xA;    AVPacket pkt;&#xA;&#xA;    int out_size, size, outbuf_size;&#xA;&#xA;    AVFrame *picture;&#xA;    uint8_t *outbuf, *picture_buf;&#xA;&#xA;    AVRational rp;   &#xA;&#xA;    rp.den = 1;&#xA;    rp.num = 25;&#xA;    uint8_t endcode[] = { 0, 0, 1, 0xb7 };&#xA;&#xA;    codec = avcodec_find_encoder(CODEC_ID_H263);&#xA;&#xA;    c = avcodec_alloc_context3(codec);&#xA;    picture= avcodec_alloc_frame();&#xA;    c->bit_rate = 400000;&#xA;    /* resolution must be a multiple of two */&#xA;    c->width = 352;&#xA;    c->height = 288;&#xA;    /* frames per second */&#xA;    //c->time_base= (AVRational){1,25};&#xA;    c->time_base = rp;&#xA;    c->gop_size = 10; /* emit one intra frame every ten frames */&#xA;    c->max_b_frames=1;&#xA;    c->pix_fmt = PIX_FMT_YUV420P;&#xA;    avcodec_open(c, codec);&#xA;&#xA;&#xA;    outbuf_size = 100000;&#xA;    outbuf = (uint8_t*)malloc(outbuf_size);&#xA;    size = c->width * c->height;&#xA;    picture_buf = (uint8_t*)malloc((size * 3) / 2); /* size for YUV 420 */&#xA;&#xA;    picture->data[0] = picture_buf;&#xA;    picture->data[1] = picture->data[0] &#x2B; size;&#xA;    picture->data[2] = picture->data[1] &#x2B; size / 4;&#xA;    picture->linesize[0] = c->width;&#xA;    picture->linesize[1] = c->width / 2;&#xA;    picture->linesize[2] = c->width / 2;&#xA;&#xA;    /* encode 1 second of video */&#xA;    for(i=0;i&lt;25;i&#x2B;&#x2B;) {&#xA;        fflush(stdout);&#xA;        /* prepare a dummy image */&#xA;        /* Y */&#xA;        for(y=0;yheight;y&#x2B;&#x2B;) {&#xA;            for(x=0;xwidth;x&#x2B;&#x2B;) {&#xA;                picture->data[0][y * picture->linesize[0] &#x2B; x] = x &#x2B; y &#x2B; i * 3;&#xA;            }&#xA;        }&#xA;        /* Cb and Cr */&#xA;        for(y=0;yheight/2;y&#x2B;&#x2B;) {&#xA;            for(x=0;xwidth/2;x&#x2B;&#x2B;) {&#xA;                picture->data[1][y * picture->linesize[1] &#x2B; x] = 128 &#x2B; y &#x2B; i * 2;&#xA;                picture->data[2][y * picture->linesize[2] &#x2B; x] = 64 &#x2B; x &#x2B; i * 5;&#xA;            }&#xA;        }&#xA;        /* encode the image */&#xA;&#xA;        **Crash is here** --->                 ///////////////////////////////////////////////////&#xA;        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);&#xA;&#xA;        printf("encoding frame %3d (size=%5d)\n", i, out_size);&#xA;        fwrite(outbuf, 1, out_size, f);&#xA;    }&#xA;    /* get the delayed frames */&#xA;    for(; out_size; i&#x2B;&#x2B;) {&#xA;        fflush(stdout);&#xA;        out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);&#xA;        printf("write frame %3d (size=%5d)\n", i, out_size);&#xA;        fwrite(outbuf, 1, out_size, f);&#xA;    }&#xA;    /* add sequence end code to have a real mpeg file */&#xA;    outbuf[0] = 0x00;&#xA;    outbuf[1] = 0x00;&#xA;    outbuf[2] = 0x01;&#xA;    outbuf[3] = 0xb7;&#xA;    fwrite(outbuf, 1, 4, f);&#xA;    fclose(f);&#xA;    free(picture_buf);&#xA;    free(outbuf);&#xA;&#xA;    avcodec_close(c);&#xA;    av_free(c);&#xA;    av_free(picture);&#xA;    printf("\n");&#xA;    return 0;&#xA;}&#xA;

    &#xA;