Recherche avancée

Médias (1)

Mot : - Tags -/lev manovitch

Autres articles (78)

  • Personnaliser en ajoutant son logo, sa bannière ou son image de fond

    5 septembre 2013, par

    Certains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;

  • Mise à jour de la version 0.1 vers 0.2

    24 juin 2013, par

    Explications des différents changements notables lors du passage de la version 0.1 de MediaSPIP à la version 0.3. Quelles sont les nouveautés
    Au niveau des dépendances logicielles Utilisation des dernières versions de FFMpeg (>= v1.2.1) ; Installation des dépendances pour Smush ; Installation de MediaInfo et FFprobe pour la récupération des métadonnées ; On n’utilise plus ffmpeg2theora ; On n’installe plus flvtool2 au profit de flvtool++ ; On n’installe plus ffmpeg-php qui n’est plus maintenu au (...)

  • Participer à sa traduction

    10 avril 2011

    Vous pouvez nous aider à améliorer les locutions utilisées dans le logiciel ou à traduire celui-ci dans n’importe qu’elle nouvelle langue permettant sa diffusion à de nouvelles communautés linguistiques.
    Pour ce faire, on utilise l’interface de traduction de SPIP où l’ensemble des modules de langue de MediaSPIP sont à disposition. ll vous suffit de vous inscrire sur la liste de discussion des traducteurs pour demander plus d’informations.
    Actuellement MediaSPIP n’est disponible qu’en français et (...)

Sur d’autres sites (11910)

  • On-demand and seamless transcoding of individual HLS segments

    5 janvier 2024, par Omid Ariyan

    Background

    


    I've been meaning to implement on-demand transcoding of certain video formats such as ".mkv", ".wmv", ".mov", etc. in order to serve them on a media management server using ASP.NET Core 6.0, C# and ffmpeg.

    


    My Approach

    


    The approach I've decided to use is to serve a dynamically generated .m3u8 file which is simply generated using a segment duration of choice e.g. 10s and the known video duration. Here's how I've done it. Note that the resolution is currently not implemented and discarded :

    


    public string GenerateVideoOnDemandPlaylist(double duration, int segment)
{
   double interval = (double)segment;
   var content = new StringBuilder();

   content.AppendLine("#EXTM3U");
   content.AppendLine("#EXT-X-VERSION:6");
   content.AppendLine(String.Format("#EXT-X-TARGETDURATION:{0}", segment));
   content.AppendLine("#EXT-X-MEDIA-SEQUENCE:0");
   content.AppendLine("#EXT-X-PLAYLIST-TYPE:VOD");
   content.AppendLine("#EXT-X-INDEPENDENT-SEGMENTS");

   for (double index = 0; (index * interval) < duration; index++)
   {
      content.AppendLine(String.Format("#EXTINF:{0:#.000000},", ((duration - (index * interval)) > interval) ? interval : ((duration - (index * interval)))));
      content.AppendLine(String.Format("{0:00000}.ts", index));
   }

   content.AppendLine("#EXT-X-ENDLIST");

   return content.ToString();
}

[HttpGet]
[Route("stream/{id}/{resolution}.m3u8")]
public IActionResult Stream(string id, string resolution)
{
   double duration = RetrieveVideoLengthInSeconds();
   return Content(GenerateVideoOnDemandPlaylist(duration, 10), "application/x-mpegURL", Encoding.UTF8);
}


    


    Here's an example of how the .m3u8 file looks like :

    


    #EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXTINF:10.000000,
00000.ts
#EXTINF:3.386667,
00001.ts
#EXT-X-ENDLIST


    


    So the player would ask for 00000.ts, 00001.ts, etc. and the next step is to have them generated on demand :

    


    public byte[] GenerateVideoOnDemandSegment(int index, int duration, string path)&#xA;{&#xA;   int timeout = 30000;&#xA;   int totalWaitTime = 0;&#xA;   int waitInterval = 100;&#xA;   byte[] output = Array.Empty<byte>();&#xA;   string executable = "/opt/homebrew/bin/ffmpeg";&#xA;   DirectoryInfo temp = Directory.CreateDirectory(System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName()));&#xA;   string format = System.IO.Path.Combine(temp.FullName, "output-%05d.ts");&#xA;&#xA;   using (Process ffmpeg = new())&#xA;   {&#xA;      ffmpeg.StartInfo.FileName = executable;&#xA;&#xA;      ffmpeg.StartInfo.Arguments = String.Format("-ss {0} ", index * duration);&#xA;      ffmpeg.StartInfo.Arguments &#x2B;= String.Format("-y -t {0} ", duration);&#xA;      ffmpeg.StartInfo.Arguments &#x2B;= String.Format("-i \"{0}\" ", path);&#xA;      ffmpeg.StartInfo.Arguments &#x2B;= String.Format("-c:v libx264 -c:a aac ");&#xA;      ffmpeg.StartInfo.Arguments &#x2B;= String.Format("-segment_time {0} -reset_timestamps 1 -break_non_keyframes 1 -map 0 ", duration);&#xA;      ffmpeg.StartInfo.Arguments &#x2B;= String.Format("-initial_offset {0} ", index * duration);&#xA;      ffmpeg.StartInfo.Arguments &#x2B;= String.Format("-f segment -segment_format mpegts {0}", format);&#xA;&#xA;      ffmpeg.StartInfo.CreateNoWindow = true;&#xA;      ffmpeg.StartInfo.UseShellExecute = false;&#xA;      ffmpeg.StartInfo.RedirectStandardError = false;&#xA;      ffmpeg.StartInfo.RedirectStandardOutput = false;&#xA;&#xA;      ffmpeg.Start();&#xA;&#xA;      do&#xA;      {&#xA;         Thread.Sleep(waitInterval);&#xA;         totalWaitTime &#x2B;= waitInterval;&#xA;      }&#xA;      while ((!ffmpeg.HasExited) &amp;&amp; (totalWaitTime &lt; timeout));&#xA;&#xA;      if (ffmpeg.HasExited)&#xA;      {&#xA;         string filename = System.IO.Path.Combine(temp.FullName, "output-00000.ts");&#xA;&#xA;         if (!File.Exists(filename))&#xA;         {&#xA;            throw new FileNotFoundException("Unable to find the generated segment: " &#x2B; filename);&#xA;         }&#xA;&#xA;         output = File.ReadAllBytes(filename);&#xA;      }&#xA;      else&#xA;      {&#xA;         // It&#x27;s been too long. Kill it!&#xA;         ffmpeg.Kill();&#xA;      }&#xA;   }&#xA;&#xA;   // Remove the temporary directory and all its contents.&#xA;   temp.Delete(true);&#xA;&#xA;   return output;&#xA;}&#xA;&#xA;[HttpGet]&#xA;[Route("stream/{id}/{index}.ts")]&#xA;public IActionResult Segment(string id, int index)&#xA;{&#xA;   string path = RetrieveVideoPath(id);&#xA;   return File(GenerateVideoOnDemandSegment(index, 10, path), "application/x-mpegURL", true);&#xA;}&#xA;</byte>

    &#xA;

    So as you can see, here's the command I use to generate each segment incrementing -ss and -initial_offset by 10 for each segment :

    &#xA;

    ffmpeg -ss 0 -y -t 10 -i "video.mov" -c:v libx264 -c:a aac -segment_time 10 -reset_timestamps 1 -break_non_keyframes 1 -map 0 -initial_offset 0 -f segment -segment_format mpegts /var/folders/8h/3xdhhky96b5bk2w2br6bt8n00000gn/T/4ynrwu0q.z24/output-%05d.ts&#xA;

    &#xA;

    The Problem

    &#xA;

    Things work on a functional level, however the transition between segments is slightly glitchy and especially the audio has very short interruptions at each 10 second mark. How can I ensure the segments are seamless ? What can I improve in this process ?

    &#xA;

  • Concat video files using ffmpeg in individual subfolders with shell script [closed]

    18 août 2022, par Weatherdark

    I had a Windows script that would do what I want, but I switched my server to Unraid so now I need a new script. Anyway, enough backstory.

    &#xA;

    I regularly have media that is named in a style like "Videoname CD(Number).ext". They get stored in subfolders called Videoname with a different folder for each video.

    &#xA;

    What I need is a script that goes through each subfolder and creates a concat.txt file with the names of each video file ending in CD(number) in it, in numerical order, that will then call ffmpeg to concat the files using the concat.txt in each subfolder, placing the video file (named after the subfolder) into a folder like /mnt/User/Pool/Finished/Videofile. Then, hopefully it will delete the concat.txt file so I know which folders are finished with a quick look.

    &#xA;

    I know the ffmpeg concat options for that part, I just have no idea what to use to make sure the resulting video file is named after the subfolder it came from.

    &#xA;

    I could do this in Windows (albeit in a hacky, not very pretty way), but I have no idea how to accomplish this in Linux.

    &#xA;

    As an example...

    &#xA;

    &#xA;

    /mnt/User/Pool/Concat/10.10.2022.0034.Recording/10.10.2022.0034.Recording&#xA;CD1.mp4&#xA;/mnt/User/Pool/Concat/10.10.2022.0034.Recording/10.10.2022.0034.Recording&#xA;CD2.mp4&#xA;/mnt/User/Pool/Concat/10.10.2022.0034.Recording/10.10.2022.0034.Recording&#xA;CD3.mp4&#xA;/mnt/User/Pool/Concat/10.10.2022.0034.Recording/10.10.2022.0034.Recording&#xA;CD4.mp4&#xA;/mnt/User/Pool/Concat/10.11.2022.0254.Recording/10.11.2022.0254.Recording&#xA;CD1.mp4&#xA;/mnt/User/Pool/Concat/10.11.2022.0254.Recording/10.11.2022.0254.Recording&#xA;CD2.mp4&#xA;/mnt/User/Pool/Concat/10.11.2022.0254.Recording/10.11.2022.0254.Recording&#xA;CD3.mp4&#xA;/mnt/User/Pool/Concat/10.11.2022.0254.Recording/10.11.2022.0254.Recording&#xA;CD4.mp4

    &#xA;

    Put through ffmpeg to concat, results in files

    &#xA;

    /mnt/User/Pool/Finished/10.10.2022.0034.Recording.mp4

    &#xA;

    /mnt/User/Pool/Finished/10.11.2022.0254.Recording.mp4

    &#xA;

    &#xA;

    Hopefully that makes sense.

    &#xA;

    Someone closed this because it wasn't "focused enough" and didn't focus on one thing... but there is ONLY one thing that it needs to do.

    &#xA;

    I have no idea what they would want me to change to fix what isn't broken, so I fundamentally am at a loss. The script just needs to search through subfolders, create a concat.txt file and send that file to ffmpeg creating the new file, named after the folder, in a new location. That is literally as focused as I can make it.

    &#xA;

  • Core : Error hidden but input error class not removed

    7 janvier 2016, par Arkni
    Core : Error hidden but input error class not removed
    

    When a field has one rule with option `depends` specified and this
    dependency mismatch, the plugin will remove it, so that field will not be
    validated on submit by the the rule in question. So if that field is
    already invalid, only the error message will be hidden and the error class
    will remain.

    This commit fixes this issue.

    Fixes #1632