
Recherche avancée
Médias (2)
-
SPIP - plugins - embed code - Exemple
2 septembre 2013, par
Mis à jour : Septembre 2013
Langue : français
Type : Image
-
Publier une image simplement
13 avril 2011, par ,
Mis à jour : Février 2012
Langue : français
Type : Video
Autres articles (93)
-
Amélioration de la version de base
13 septembre 2013Jolie 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, parLe 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, parLa 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 Khirnovffmpeg : 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 AlidoustI’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(&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 & 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(&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(&mediaBuffer), "Could not convert IMFSample to contagiuous buffer", E_FAIL);
RET_IF_FAILED(mediaBuffer->GetCurrentLength(&length), "Could not get buffer length", E_FAIL);
RET_IF_FAILED(mediaBuffer->Lock(&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(&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, &pkt))) {
RET_IF_FAILED_AV(av_interleaved_write_frame(this->fmtContext, &pkt), "Could not write the received packet.", E_FAIL);
}
av_packet_unref(&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 RiceSomething 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 pawelmI 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.


.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 :


- 

- 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.
- 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.






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) :


// get params - chunk number and stream identifier
$prefix = $_GET['n'];
$num = $_GET['c'];
$isFirst = false;
$isLast = isset($_GET['f']) && $_GET['f'];

if(str_replace('0', '', $num) == '') {
 mkdir('videos/'.$prefix);
 $isFirst = true;
}

$fp = 'videos\\'.$prefix.'\\'.$num.'.webm';
$msg = 'got '.$fp;

$data = file_get_contents('php://input');
file_put_contents($fp, $data);

// we determine exact chunk length
$detailsTxt = 'videos\\'.$prefix.'\\'.$num.'.txt';
exec("ffmpeg -i .\\$fp -f null - > .\\$detailsTxt 2>&1");

preg_match('/(\d{2}:\d{2}:(\d{2}.\d{2}))/', file_get_contents($detailsTxt), $matches);
$matches = array_filter($matches);
$duration = (float)trim($matches[2], '0');

$durationTxt = 'videos\\'.$prefix.'\\'.$num.'_dur.txt';
file_put_contents($durationTxt, $duration);

// ts convertion

// counting start timestamp
$FPS = 25;
$t0 = 0;
$cursorTxt = 'videos\\'.$prefix.'\\cursor.txt';
if(file_exists($cursorTxt)) $t0 = (float)file_get_contents($cursorTxt);
file_put_contents($cursorTxt, $t0 + $duration /*+ 1/$FPS*/);

$fp2 = str_replace('.webm', '.ts', $fp);
$details2Txt = 'videos\\'.$prefix.'\\'.$num.'_conv.txt';

$convertCommand = [
 'ffmpeg',
 '-v', 'quiet',
 '-loglevel', 'error',
 '-i', ".\\$fp",
 '-vcodec', 'libx264',
 '-acodec', 'aac',
 '-r', $FPS,
 '-profile:v', 'baseline',
 '-b:v', '800k',
 '-b:a', '48k',
 '-f', 'mpegts',
 '-strict', 'experimental',
 '-mpegts_copyts', '1',
 '-filter:v', 'setpts=PTS+' . $t0 . '/TB', // $t0
 '-y',
 ".\\$fp2",
 "> .\\$details2Txt 2>&1"
];

exec(implode(" ", $convertCommand));

// generating m3u8 file

// counting max duration
$maxDuration = $duration;
$durationTxt = 'videos\\'.$prefix.'\\duration.txt';
if(file_exists($durationTxt)) {
 $tempDuration = (float)file_get_contents($durationTxt);
 if($tempDuration > $maxDuration) $maxDuration = $tempDuration;
 else file_put_contents($durationTxt, $maxDuration);
}else file_put_contents($durationTxt, $maxDuration);

file_put_contents($cursorTxt, $t0 + $duration);

$m3u8File = 'videos\\'.$prefix.'\\playlist.m3u8';
$m3u8Content = [];

$counter = 0;
do {
 $paddedCounter = str_pad($counter, 5, '0', STR_PAD_LEFT);
 $chunkFile = 'videos\\'.$prefix.'\\'.$paddedCounter.'.ts';
 if(!file_exists($chunkFile)) break;
 $counter++;
}while(true);

$m3u8Content[] = "#EXTM3U";
$m3u8Content[] = "#EXT-X-VERSION:3";
$m3u8Content[] = "#EXT-X-MEDIA-SEQUENCE:$counter";
$m3u8Content[] = "#EXT-X-ALLOW-CACHE:YES";
$m3u8Content[] = "#EXT-X-TARGETDURATION:".ceil($maxDuration);
$m3u8Content[] = "";

$counter = 0;
do {
 $paddedCounter = str_pad($counter, 5, '0', STR_PAD_LEFT);
 $chunkFile = 'videos\\'.$prefix.'\\'.$paddedCounter.'.ts';
 if(!file_exists($chunkFile)) break;

 $durationTxt = 'videos\\'.$prefix.'\\'.$paddedCounter.'_dur.txt';
 $duration = (float)file_get_contents($durationTxt);

 $m3u8Content[] = "#EXTINF:$duration,";
 $m3u8Content[] = "$paddedCounter.ts";

 $counter++;
}while(true);

if($isLast) $m3u8Content[] = "#EXT-X-ENDLIST";
$m3u8Content[] = "";

file_put_contents($m3u8File, implode("\n", $m3u8Content));



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.