Recherche avancée

Médias (91)

Autres articles (23)

  • Publier sur MédiaSpip

    13 juin 2013

    Puis-je poster des contenus à partir d’une tablette Ipad ?
    Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir

  • Supporting all media types

    13 avril 2011, par

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

  • Librairies et logiciels spécifiques aux médias

    10 décembre 2010, par

    Pour un fonctionnement correct et optimal, plusieurs choses sont à prendre en considération.
    Il est important, après avoir installé apache2, mysql et php5, d’installer d’autres logiciels nécessaires dont les installations sont décrites dans les liens afférants. Un ensemble de librairies multimedias (x264, libtheora, libvpx) utilisées pour l’encodage et le décodage des vidéos et sons afin de supporter le plus grand nombre de fichiers possibles. Cf. : ce tutoriel ; FFMpeg avec le maximum de décodeurs et (...)

Sur d’autres sites (6762)

  • Using ffmpeg shared library in a commercial C/C++ application

    9 mai 2017, par Peter

    We have a C++-based application that runs on Windows, Mac, and Linux. I now need to add h.264 and h.265 decoding within this application. It seems ffmpeg will do the trick.

    As ours is a commercial application, we cannot disclose the source code to public. However, as I understand, FFMpeg is based on LGPL licensing requirements. Going through various articles on LGPL requirements, it seems I can use ffmpeg without disclosing our source code as long as :

    1. I build ffmpeg as a shared libraries and make sure that I don’t use "—enable-gpl" flag during configuration.
    2. I acknowledge in our About dialog box that we are using ffmpeg shared libraries.

    Can someone please verify if this more or less meets the requirements ? Regards.

    Note that I need ffmpeg only to decode and not to encode. Therefore, I don’t have to use "—enable-libx264" and "—enable-libx265" flags.

  • dockerized python application takes a long time to trim a video with ffmpeg

    15 avril 2024, par Ukpa Uchechi

    The project trims YouTube videos.

    


    When I ran the ffmpeg command on the terminal, it didn't take too long to respond. The code below returns the trimmed video to the front end but it takes too long to respond. A 10 mins trim length takes about 5mins to respond. I am missing something, but I can't pinpoint the issue.

    


    backend

    


    main.py

    


    import os

from flask import Flask, request, send_file
from flask_cors import CORS, cross_origin


app = Flask(__name__)
cors = CORS(app)


current_directory = os.getcwd()
folder_name = "youtube_videos"
save_path = os.path.join(current_directory, folder_name)
output_file_path = os.path.join(save_path, 'video.mp4')

os.makedirs(save_path, exist_ok=True)

def convert_time_seconds(time_str):
    hours, minutes, seconds = map(int, time_str.split(':'))
    total_seconds = (hours * 3600) + (minutes * 60) + seconds

    return total_seconds
def convert_seconds_time(total_seconds):
    new_hours = total_seconds // 3600
    total_seconds %= 3600
    new_minutes = total_seconds // 60
    new_seconds = total_seconds % 60

    new_time_str = f'{new_hours:02}:{new_minutes:02}:{new_seconds:02}'

    return new_time_str
def add_seconds_to_time(time_str, seconds_to_add):
    total_seconds = convert_time_seconds(time_str)

    total_seconds -= seconds_to_add
    new_time_str = convert_seconds_time(total_seconds)

    return new_time_str

def get_length(start_time, end_time):
    start_time_seconds = convert_time_seconds(start_time)
    end_time_seconds = convert_time_seconds(end_time)

    length = end_time_seconds - start_time_seconds

    length_str = convert_seconds_time(length)
    return length_str
    
def download_url(url):
    command = [
        "yt-dlp",
        "-g",
        url
    ]
    
    try:
        links = subprocess.run(command, capture_output=True, text=True, check=True)
        
        video, audio = links.stdout.strip().split("\n")
        
        return video, audio

    except subprocess.CalledProcessError as e:
        print(f"Command failed with return code {e.returncode}.")
        print(f"Error output: {e.stderr}")
        return None
    except ValueError:
        print("Error: Could not parse video and audio links.")
        return None
    


def download_trimmed_video(video_link, audio_link, start_time, end_time):
    new_start_time = add_seconds_to_time(start_time, 30)
    new_end_time = get_length(start_time, end_time)

    if os.path.exists(output_file_path):
        os.remove(output_file_path)


    command = [
        'ffmpeg',
        '-ss', new_start_time + '.00',
        '-i', video_link,
        '-ss', new_start_time + '.00',
        '-i', audio_link,
        '-map', '0:v',
        '-map', '1:a',
        '-ss', '30',
        '-t', new_end_time + '.00',
        '-c:v', 'libx264',
        '-c:a', 'aac',
        output_file_path
    ]
    try:
        result = subprocess.run(command, capture_output=True, text=True, check=True)

        if result.returncode == 0:
            return "Trimmed video downloaded successfully!"
        else:
            return "Error occurred while downloading trimmed video"
    except subprocess.CalledProcessError as e:
        print(f"Command failed with return code {e.returncode}.")
        print(f"Error output: {e.stderr}")


app = Flask(__name__)


@app.route('/trimvideo', methods =["POST"])
@cross_origin()
def trim_video():
    print("here")
    data = request.get_json()
    video_link, audio_link = download_url(data["url"])
    if video_link and audio_link:
        print("Downloading trimmed video...")
        download_trimmed_video(video_link, audio_link, data["start_time"], data["end_time"])
        response = send_file(output_file_path, as_attachment=True, download_name='video.mp4')
    
        response.status_code = 200

        return response
    else:
        return "Error downloading video", 400

    




if __name__ == '__main__':
    app.run(debug=True, port=5000, host='0.0.0.0')


    


    dockerfile

    


    FROM ubuntu:latest

# Update the package list and install wget and ffmpeg
RUN apt-get update \
    && apt-get install -y wget ffmpeg python3 python3-pip \
    && rm -rf /var/lib/apt/lists/*

# Download the latest version of yt-dlp and install it
RUN wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O /usr/local/bin/yt-dlp \
    && chmod a+rx /usr/local/bin/yt-dlp

WORKDIR /app

COPY main.py /app/
COPY requirements.txt /app/


RUN pip install --no-cache-dir -r requirements.txt


# Set the default command
CMD ["python3", "main.py"]


    


    requirements.txt

    


    blinker==1.7.0
click==8.1.7
colorama==0.4.6
Flask==3.0.3
Flask-Cors==4.0.0
itsdangerous==2.1.2
Jinja2==3.1.3
MarkupSafe==2.1.5
Werkzeug==3.0.2


    


    frontend

    


    App.js

    


    &#xA;import React, { useState } from &#x27;react&#x27;;&#xA;import &#x27;./App.css&#x27;;&#xA;import axios from &#x27;axios&#x27;;&#xA;async function handleSubmit(event, url, start_time, end_time, setVideoUrl, setIsSubmitted){&#xA;  event.preventDefault();&#xA;&#xA;  if( url &amp;&amp; start_time &amp;&amp; end_time){&#xA;&#xA;    try {&#xA;      setIsSubmitted(true);&#xA;    const response = await axios.post(&#x27;http://127.0.0.1:5000/trimvideo&#x27;, {&#xA;      url: url,&#xA;      start_time: start_time,&#xA;      end_time: end_time&#xA;    },&#xA;    {&#xA;      responseType: &#x27;blob&#x27;,&#xA;      headers: {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;}&#xA;    }&#xA;  )&#xA;    const blob = new Blob([response.data], { type: &#x27;video/mp4&#x27; });&#xA;    const newurl = URL.createObjectURL(blob);&#xA;&#xA;&#xA;    setVideoUrl(newurl);&#xA;    } catch (error) {&#xA;      console.error(&#x27;Error trimming video:&#x27;, error);&#xA;    }&#xA;&#xA;  } else {&#xA;    alert(&#x27;Please fill all the fields&#x27;);&#xA;  }&#xA;}&#xA;&#xA;&#xA;function App() {&#xA;  const [url, setUrl] = useState(&#x27;&#x27;);&#xA;  const [startTime, setStartTime] = useState(&#x27;&#x27;);&#xA;  const [endTime, setEndTime] = useState(&#x27;&#x27;);&#xA;  const [videoUrl, setVideoUrl] = useState(&#x27;&#x27;);&#xA;  const [isSubmitted, setIsSubmitted] = useState(false);&#xA;  return (&#xA;    <div classname="App">&#xA;        <div classname="app-header">TRIM AND DOWNLOAD YOUR YOUTUBE VIDEO HERE</div>&#xA;        <input classname="input-url" placeholder="&#x27;Enter" value="{url}" />setUrl(e.target.value)}/>&#xA;        <div classname="input-container">&#xA;          <input classname="start-time-url" placeholder="start time" value="{startTime}" />setStartTime(e.target.value)}/>&#xA;          <input classname="end-time-url" placeholder="end time" value="{endTime}" />setEndTime(e.target.value)}/>&#xA;        &#xA;        </div>&#xA;        {&#xA;          !isSubmitted &amp;&amp; <button>> handleSubmit(event, url, startTime, endTime, setVideoUrl, setIsSubmitted)} className=&#x27;trim-button&#x27;>Trim</button>&#xA;        }&#xA;&#xA;        {&#xA;         ( isSubmitted &amp;&amp; !videoUrl) &amp;&amp;   <div classname="dot-pulse"></div>&#xA;        }&#xA;&#xA;&#xA;        {&#xA;          videoUrl &amp;&amp; <video controls="controls" autoplay="autoplay" width="500" height="360">&#xA;          <source src="{videoUrl}" type="&#x27;video/mp4&#x27;"></source>&#xA;        </video>&#xA;        }&#xA;&#xA;        &#xA;    </div>&#xA;  );&#xA;}&#xA;&#xA;export default App;&#xA;

    &#xA;

  • Paperclip Upload Video Without Styles

    16 mars 2017, par Moamen Naanou

    Background :

    In my app, there is a model has image attachment using paperclip gem, now as per new requirements, I have to let the same attachment accept MP4 video files as well and the only validation I have to implement is about file size.

    Product Model (with image attachment only) :

    class Product &lt; ActiveRecord::Base
     has_attached_file :file,
                       :styles => { medium: '300x300>', thumb: '100x100>' },
                       :processors => [:thumbnail],
                       :url => '/assets/:id/:style/:hash.:extension',
                       :hash_digest=>'SHA1',
                       :use_timestamp => false


     validates_attachment_content_type :file, :content_type => /\A(image)\/.*\Z/
     validates_attachment_size :file, :less_than => 5.megabytes
    end

    So after reading many related questions, to accept a video file as well, I’ve used gem paperclip-av-transcoder and installed ffmpeg (Mac) using :

    brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-frei0r --with-libas

    Then finally I’ve revised my model to be :

    class Product &lt; ActiveRecord::Base
     has_attached_file :file,
                       :styles => lambda {|file| if file.instance.is_image?
                                                   { medium: '300x300>', thumb: '100x100>' }
                                                 elsif file.instance.is_video?
                                                   {:thumb => { :geometry => "100x100#", :format => 'jpg', :time => 10}}
                                                 end },
                       :processors => lambda {|file| if file.is_image?
                                                       [:thumbnail]
                                                     elsif file.is_video?
                                                       [:transcoder]
                                                     end},
                       :url => '/assets/:id/:style/:hash.:extension',
                       :hash_digest=>'SHA1',
                       :use_timestamp => false


     validates_attachment_content_type :file, :content_type => /\A(image|video)\/.*\Z/
     validates_attachment_size :file, :less_than => 5.megabytes

     def is_video?
       file_content_type =~ %r(video)
     end

     def is_image?
       file_content_type =~ %r(image)
     end
    end

    Now the file field accepts both videos & images but the video shouldn’t be compressed, because if it is compressed, I will get IO Error [Closed Stream]

    Question :

    I’m expecting compressed MP4 file to be received from Mobile client(through REST API) and I don’t want to generate any thumb image or any other style or do any processing on this video and without installing any processor (ffmpeg in my case) and if I did so currently, I’m getting the following error because ImageMagic doesn’t work with video files :

    Paperclip::Errors::NotIdentifiedByImageMagickError

    Any ideas ?