
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 (46)
-
Websites made with MediaSPIP
2 mai 2011, parThis page lists some websites based on MediaSPIP.
-
Creating farms of unique websites
13 avril 2011, parMediaSPIP platforms can be installed as a farm, with a single "core" hosted on a dedicated server and used by multiple websites.
This allows (among other things) : implementation costs to be shared between several different projects / individuals rapid deployment of multiple unique sites creation of groups of like-minded sites, making it possible to browse media in a more controlled and selective environment than the major "open" (...) -
Les autorisations surchargées par les plugins
27 avril 2010, parMediaspip core
autoriser_auteur_modifier() afin que les visiteurs soient capables de modifier leurs informations sur la page d’auteurs
Sur d’autres sites (7803)
-
FFMPEG eating up ram in railway deployment [flask app]
23 juin 2024, par Eshan DasI created a flask app , meme generator, hosting it in railway using gunicorn, i am suspecting ffmpeg is eating the most ram.....
so what i am doing is , generating a tts, and a text adding into one of the parts of the video , and then finally combining all together


from flask import Flask, request, jsonify, send_file, url_for
from moviepy.editor import VideoFileClip, ImageClip, CompositeVideoClip, AudioFileClip, concatenate_videoclips
from pydub import AudioSegment
from PIL import Image, ImageDraw, ImageFont
from gtts import gTTS
from flask_cors import CORS
import os

app = Flask(__name__)
CORS(app)
app.config['UPLOAD_FOLDER'] = 'uploads'

def generate_video(name, profile_image_path, song_path, start_time):
 first_video = VideoFileClip("first.mp4")
 second_video = VideoFileClip("second.mp4")
 third_video = VideoFileClip("third.mp4")

 #font_path = os.path.join("fonts", "arial.ttf") # Updated font path
 font_size = 70
 font = ImageFont.load_default()
 text = name
 image_size = (second_video.w, second_video.h)
 text_image = Image.new('RGBA', image_size, (0, 0, 0, 0))
 draw = ImageDraw.Draw(text_image)
 text_width, text_height = draw.textsize(text, font=font)
 text_position = ((image_size[0] - text_width) // 2, (image_size[1] - text_height) // 2)
 draw.text(text_position, text, font=font, fill="black")

 text_image_path = os.path.join(app.config['UPLOAD_FOLDER'], f"text_{name}.png")
 text_image.save(text_image_path)

 txt_clip = ImageClip(text_image_path, duration=second_video.duration)

 tts = gTTS(text=name, lang='en')
 audio_path = os.path.join(app.config['UPLOAD_FOLDER'], f"audio_{name}.wav")
 tts.save(audio_path)

 sound = AudioSegment.from_file(audio_path)
 chipmunk_sound = sound._spawn(sound.raw_data, overrides={
 "frame_rate": int(sound.frame_rate * 1.5)
 }).set_frame_rate(sound.frame_rate)

 chipmunk_audio_path = os.path.join(app.config['UPLOAD_FOLDER'], f"chipmunk_audio_{name}.wav")
 chipmunk_sound.export(chipmunk_audio_path, format="wav")

 audio_clip_second = AudioFileClip(chipmunk_audio_path)

 second_video = CompositeVideoClip([second_video, txt_clip.set_position((45, 170))])
 second_video = second_video.set_audio(audio_clip_second)

 song = AudioSegment.from_file(song_path)
 start_ms = start_time * 1000
 cropped_song = song[start_ms:start_ms + 20000]

 chipmunk_song = cropped_song._spawn(cropped_song.raw_data, overrides={
 "frame_rate": int(cropped_song.frame_rate * 1.5)
 }).set_frame_rate(cropped_song.frame_rate)

 chipmunk_song_path = os.path.join(app.config['UPLOAD_FOLDER'], f"chipmunk_song_{name}.wav")
 chipmunk_song.export(chipmunk_song_path, format="wav")

 audio_clip_third = AudioFileClip(chipmunk_song_path)
 third_video = third_video.set_audio(audio_clip_third)

 profile_image = ImageClip(profile_image_path).set_duration(first_video.duration).resize(height=first_video.h / 8).set_position((950, 500))
 first_video = CompositeVideoClip([first_video, profile_image])
 
 profile_image = ImageClip(profile_image_path).set_duration(second_video.duration).resize(height=second_video.h / 8).set_position((950, 500))
 second_video = CompositeVideoClip([second_video, profile_image])
 
 profile_image = ImageClip(profile_image_path).set_duration(third_video.duration).resize(height=third_video.h / 8).set_position((950, 500))
 third_video = CompositeVideoClip([third_video, profile_image])

 final_video = concatenate_videoclips([first_video, second_video, third_video])
 final_video = final_video.subclip(0, 10)

 output_path = os.path.join(app.config['UPLOAD_FOLDER'], f"output_{name}.mp4")
 final_video.write_videofile(output_path, codec="libx264", audio_codec='aac')

 final_video.close()
 first_video.close()
 second_video.close()
 third_video.close()
 audio_clip_second.close()
 audio_clip_third.close()

 os.remove(audio_path)
 os.remove(text_image_path)
 os.remove(chipmunk_song_path)
 os.remove(chipmunk_audio_path)
 
 return output_path

@app.route('/generate', methods=['POST'])
async def generate():
 if not os.path.exists(app.config['UPLOAD_FOLDER']):
 os.makedirs(app.config['UPLOAD_FOLDER'])

 name = request.form['name']
 start_time = float(request.form['start_time'])

 profile_image = request.files['profile_image']
 profile_image_path = os.path.join(app.config['UPLOAD_FOLDER'], profile_image.filename)
 profile_image.save(profile_image_path)

 song = request.files['song']
 song_path = os.path.join(app.config['UPLOAD_FOLDER'], song.filename)
 song.save(song_path)

 video_path = generate_video(name, profile_image_path, song_path, start_time)
 return jsonify({"video_url": url_for('uploaded_file', filename=os.path.basename(video_path))})

@app.route('/uploads/<filename>')
def uploaded_file(filename):
 path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
 return send_file(path, as_attachment=True)

if __name__ == "__main__":
 if not os.path.exists(app.config['UPLOAD_FOLDER']):
 os.makedirs(app.config['UPLOAD_FOLDER'])
 app.run(host='0.0.0.0', port=5000)
</filename>


I am trying to solve this issue, any way to optimize my code , or any other alternative of ffmpeg which i can use , to reduce the ram consumption


-
How to hold the mpegts stream for few seconds ?
8 août 2024, par AvenHow to hold the mpegts stream for 5 seconds without changing frams's PTS ?


I tried the tsduck command as below :


aven.cheng@tgcusers-MacBook-Pro ~ % tsp -I ip 235.35.3.5:3535 -P timeshift --time 5000 -O ip 235.35.3.5:3536

* Warning: timeshift: unknown initial bitrate, discarding packets until a valid bitrate can set the buffer size



the stream of 235.35.3.5:3536 did come out 5 seconds later after i executed the above command..
But the frames' PTS of 235.35.3.5:3536 are not the same anymore. For exsample, the PTS of my target frame is 10935000 from 235.35.3.5:3535, but the PTS of my target frame has changed to 10830542 from 235.35.3.5:3536.


Is that possible to hold the stream for few seconds and also keep the PTS unchanged ? I don't necessarily have to use tsduck ; I am open to using other tools.


-
local.ERROR : ffmpeg failed to execute command
20 août 2024, par AMNA IQBALI am trying to draw points on a video.


The Video is 12 seconds long and for one second there are 17 data points which needs to be plotted on the video of one frame (1 second).

It works for 6 seconds but not for 12 seconds.

Why it's not working for longer videos ? Is there any limitations of commands in ffmpeg ?


public function overlayCoordinates(Request $request)
{
Log::info('Received request to overlay coordinates on video.');

 set_time_limit(600); // 600 seconds = 10 minutes
 try {

 $request->validate([
 'video' => 'required|file|mimes:mp4,avi,mkv,webm|max:102400', // Video max size 100MB
 'coordinates' => 'required|file|mimes:txt|max:5120', // Coordinates text file max size 5MB
 ]);

 $videoFile = $request->file('video');
 $coordinatesFile = $request->file('coordinates');

 $videoFilePath = $videoFile->getRealPath();
 $videoFileName = $videoFile->getClientOriginalName();

 // Move the video file to the desired location if needed
 $storedVideoPath = $videoFile->storeAs('public/videos', $videoFileName);

 // Open the video file using Laravel FFmpeg
 $media = FFMpeg::fromDisk('public')->open('videos/' . $videoFileName);
 $duration = $media->getDurationInSeconds();

 Log::info('Duration: ' . $duration);

 $coordinatesJson = file_get_contents($coordinatesFile->getPathname());
 $coordinatesArray = json_decode($coordinatesJson, true);

 $frameRate = 30; // Assuming a frame rate of 30 fps
 $visibilityDuration = 0.5; // Set duration to 0.5 second

 for ($currentTime = 0; $currentTime < 7; $currentTime++) {
 $filterString = ""; // Reset filter string for each frame
 $frameIndex = intval($currentTime * $frameRate); // Convert current time to an index

 if (isset($coordinatesArray['graphics'][$frameIndex])) {
 // Loop through the first 5 keypoints (or fewer if not available)
 $keypoints = $coordinatesArray['graphics'][$frameIndex]['kpts'];
 for ($i = 0; $i < min(12, count($keypoints)); $i++) {
 $keypoint = $keypoints[$i];

 $x = $keypoint['p'][0] * 1920; // Scale x coordinate to video width
 $y = $keypoint['p'][1] * 1080; // Scale y coordinate to video height

 $startTime = $frameIndex / $frameRate; // Calculate start time
 $endTime = $startTime + $visibilityDuration; // Set end time for 0.5 second duration

 // Add drawbox filter for the current keypoint
 $filterString .= "drawbox=x={$x}:y={$y}:w=10:h=10:color=red@0.5:t=fill:enable='between(t,{$startTime},{$endTime})',";
 }
 Log::info("Processing frame index: {$frameIndex}, Drawing first 5 keypoints.");
 }

 $filterString = rtrim($filterString, ',');
 
 // Apply the filter for the current frame
 if (!empty($filterString)) {
 $media->addFilter(function ($filters) use ($filterString) {
 $filters->custom($filterString);
 });
 }
 }

 $filename = uniqid() . '_overlayed.mp4';
 $destinationPath = 'videos/' . $filename;

 $format = new \FFMpeg\Format\Video\X264('aac');
 $format->setKiloBitrate(5000) // Increase bitrate for better quality
 ->setAdditionalParameters(['-profile:v', 'high', '-preset', 'veryslow', '-crf', '18']) // High profile, very slow preset, and CRF of 18 for better quality
 ->setAudioCodec('aac')
 ->setAudioKiloBitrate(192); // Higher audio bitrate
 

 // Export the video in one pass to a specific disk and directory
 $media->export()
 ->toDisk('public')
 ->inFormat($format)
 ->save($destinationPath);

 return response()->json([
 'message' => 'Video processed successfully with overlays.',
 'path' => Storage::url($destinationPath)
 ]);
 } catch (\Exception $e) {
 Log::error('Overlay process failed: ' . $e->getMessage());
 return response()->json(['error' => 'Overlay process failed. Please check logs for details.'], 500);
 }
}