
Recherche avancée
Médias (1)
-
Bug de détection d’ogg
22 mars 2013, par
Mis à jour : Avril 2013
Langue : français
Type : Video
Autres articles (28)
-
Emballe médias : à quoi cela sert ?
4 février 2011, parCe plugin vise à gérer des sites de mise en ligne de documents de tous types.
Il crée des "médias", à savoir : un "média" est un article au sens SPIP créé automatiquement lors du téléversement d’un document qu’il soit audio, vidéo, image ou textuel ; un seul document ne peut être lié à un article dit "média" ; -
Multilang : améliorer l’interface pour les blocs multilingues
18 février 2011, parMultilang est un plugin supplémentaire qui n’est pas activé par défaut lors de l’initialisation de MediaSPIP.
Après son activation, une préconfiguration est mise en place automatiquement par MediaSPIP init permettant à la nouvelle fonctionnalité d’être automatiquement opérationnelle. Il n’est donc pas obligatoire de passer par une étape de configuration pour cela. -
Supporting all media types
13 avril 2011, parUnlike most software and media-sharing platforms, MediaSPIP aims to manage as many different media types as possible. The following are just a few examples from an ever-expanding list of supported formats : images : png, gif, jpg, bmp and more audio : MP3, Ogg, Wav and more video : AVI, MP4, OGV, mpg, mov, wmv and more text, code and other data : OpenOffice, Microsoft Office (Word, PowerPoint, Excel), web (html, CSS), LaTeX, Google Earth and (...)
Sur d’autres sites (8346)
-
Revision 70542 : Vérification SIREN/SIRET : tolérer une chaîne contenant des espaces. Ca ...
9 mars 2013, par tcharlss@… — LogVérification SIREN/SIRET : tolérer une chaîne contenant des espaces.
Ca permet une écriture plus lisible => ; 493 056 592 00022 au lieu de 49305659200022 par exemple. -
Anomalie #4623 : Styles des fieldset dans l’espace privé
18 avril 2021, par RastaPopoulos ♥Oui marcimat, pour moi la règle c’est qu’un fieldset c’est comme un autre champ en plus gros, donc toujours à utiliser au même niveau que les div.editer. Si on commence à avoir des exceptions dans la structure (parfois à tel endroit parfois pas) après pour les marges c’est l’horreur à styler, faire des exceptions etc. Je pense qu’il faut garder la règle un fieldset == un div.editer en plus gros.
Et c’est dans le fieldset qu’il y a un sous div.editer-groupe qui refait une "liste de lignes de champs", pouvant donc de nouveau contenir des div.editer et/ou des fieldset.fieldset (vrai groupe) et/ou fieldset.editer (groupe de choix comme un champ aussi)
La seule simplification c’est que les vrais fieldsets n’auraient plus à être eux-mêmes dans un div.fieldset, mais directement au même niveau que les champs frères div.editer et fieldset.editer.
-
How to HLS-live-stream incoming batches of individual frames, "appending" to a m3u8 playlist in real time, with ffmpeg ?
20 novembre 2024, par RobMy overall goal :



Server-side :



- 

- I have batches of sequential, JPEG-encoded frames (8-16) arriving from time to time, generated at roughly 2 FPS.
- I would like to host an HLS live stream, where, when a new batch of frames arrives, I encode those new frames as h264
.ts
segments withffmpeg
, and have the new.ts
segments automatically added to an HLS stream (e.g..m3u8
file).







Client/browser-side :



- 

- When the
.m3u8
is updated, I would like the video stream being watched to simply "continue", advancing from the point where new.ts
segments have been added. - I do not need the user to scrub backwards in time, the client just needs to support live observation of the stream.










My current approach :



Server-side :



To generate the "first" few segments of the stream, I'm attempting the below (just command-line for now to get ffmpeg working right, but ultimately will be automated via a Python script) :



For reference, I'm using ffmpeg version 3.4.6-0ubuntu0.18.04.1.



ffmpeg -y -framerate 2 -i /frames/batch1/frame_%d.jpg \
 -c:v libx264 -crf 21 -preset veryfast -g 2 \
 -f hls -hls_time 4 -hls_list_size 4 -segment_wrap 4 -segment_list_flags +live video/stream.m3u8




where the
/frames/batch1/
folder contains a sequence of frames (e.g. frame_01.jpg, frame_02.jpg, etc...). This already doesn't appear to work correctly, because it keeps adding#EXT-X-ENDLIST
to the end of the.m3u8
file, which as I understand is not correct for a live HLS stream - here's what that generates :


#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:4.000000,
stream0.ts
#EXTINF:4.000000,
stream1.ts
#EXTINF:2.000000,
stream2.ts
#EXT-X-ENDLIST




I can't figure out how to suppress
#EXT-X-ENDLIST
here - this is problem #1.


Then, to generate subsequent segments (e.g. when new frames become available), I'm trying this :



ffmpeg -y -framerate 2 -start_number 20 -i /frames/batch2/frame_%d.jpg \
 -c:v libx264 -crf 21 -preset veryfast -g 2 \
 -f hls -hls_time 4 -hls_list_size 4 -segment_wrap 4 -segment_list_flags +live video/stream.m3u8




Unfortunately, this does not work the way I want it to. It simply overwrites
stream.m3u8
, does and does not advance#EXT-X-MEDIA-SEQUENCE
, it does not index the new.ts
files correctly, and it also includes the undesirable#EXT-X-ENDLIST
- this is the output of that command :


#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:4.000000,
stream0.ts
#EXTINF:4.000000,
stream1.ts
#EXTINF:3.000000,
stream2.ts
#EXT-X-ENDLIST




Fundamentally, I can't figure out how to "append" to an existing
.m3u8
in a way that makes sense for HLS live streaming. That's essentially problem #2.


For hosting the stream, I'm using a simple Flask app - which appears to be working the way I intend - here's what I'm doing for reference :



@app.route('/video/')
def stream(file_name):
 video_dir = './video'
 return send_from_directory(directory=video_dir, filename=file_name)




Client-side :



I'm trying HLS.js in Chrome - basically boils down to this :



<video></video>

...

<code class="echappe-js"><script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>

<script>&#xA; var video = document.getElementById(&#x27;video1&#x27;);&#xA; if (Hls.isSupported()) {&#xA; var hls = new Hls();&#xA; hls.loadSource(&#x27;/video/stream.m3u8&#x27;);&#xA; hls.attachMedia(video);&#xA; hls.on(Hls.Events.MANIFEST_PARSED, function() {&#xA; video.play();&#xA; });&#xA; }&#xA; else if (video.canPlayType(&#x27;application/vnd.apple.mpegurl&#x27;)) {&#xA; video.src = &#x27;/video/stream.m3u8&#x27;;&#xA; video.addEventListener(&#x27;loadedmetadata&#x27;, function() {&#xA; video.play();&#xA; });&#xA; }&#xA;</script>




I'd like to think that what I'm trying to do doesn't require a more complex approach than what I'm trying above, but since what I'm trying to far definitely isn't working, I'm starting to think I need to come at this from a different angle. Any ideas on what I'm missing ?



Edit :



I've also attempted the same (again in Chrome) with
video.js
, and am seeing similar behavior - in particular, when I manually update the backingstream.m3u8
(with no#EXT-X-ENDLIST
tag),videojs
never picks up the new changes to the live stream, and just buffers/hangs indefinitely.


<video class="video-js vjs-default-skin" muted="muted" controls="controls">
 <source type="application/x-mpegURL" src="/video/stream.m3u8">
</source></video>

...

<code class="echappe-js"><script>&#xA; var player = videojs(&#x27;video1&#x27;);&#xA; player.play();&#xA;</script>




For example, if I start with this initial version of
stream.m3u8
:


#EXTM3U
#EXT-X-PLAYLIST-TYPE:EVENT
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:4.000000,
stream0.ts
#EXTINF:4.000000,
stream1.ts
#EXTINF:2.000000,
stream2.ts




and then manually update it server-side to this :



#EXTM3U
#EXT-X-PLAYLIST-TYPE:EVENT
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:3
#EXTINF:4.000000,
stream3.ts
#EXTINF:4.000000,
stream4.ts
#EXTINF:3.000000,
stream5.ts




the video.js control just buffers indefinitely after only playing the first 3 segments (stream*.ts 0-2), which isn't what I'd expect to happen (I'd expect it to continue playing stream*.ts 3-5 once
stream.m3u8
is updated andvideo.js
makes a request for the latest version of the playlist).