
Recherche avancée
Médias (1)
-
Richard Stallman et le logiciel libre
19 octobre 2011, par
Mis à jour : Mai 2013
Langue : français
Type : Texte
Autres articles (68)
-
MediaSPIP Core : La Configuration
9 novembre 2010, parMediaSPIP Core fournit par défaut trois pages différentes de configuration (ces pages utilisent le plugin de configuration CFG pour fonctionner) : une page spécifique à la configuration générale du squelettes ; une page spécifique à la configuration de la page d’accueil du site ; une page spécifique à la configuration des secteurs ;
Il fournit également une page supplémentaire qui n’apparait que lorsque certains plugins sont activés permettant de contrôler l’affichage et les fonctionnalités spécifiques (...) -
Ajouter des informations spécifiques aux utilisateurs et autres modifications de comportement liées aux auteurs
12 avril 2011, parLa manière la plus simple d’ajouter des informations aux auteurs est d’installer le plugin Inscription3. Il permet également de modifier certains comportements liés aux utilisateurs (référez-vous à sa documentation pour plus d’informations).
Il est également possible d’ajouter des champs aux auteurs en installant les plugins champs extras 2 et Interface pour champs extras. -
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 (12338)
-
How to load file in ffmpeg in chunks ?
18 mars, par developer1I'm having a problem when loading a larger file with ffmpeg in safari mobile, it crashes while doing that.


Currently I'm loading the whole file at once
await ffmpeg.writeFile(inputFileName, await fetchFile(file));
and to my understanding safari tries to load it in-memory in one go and fails.

How can I work around this issue ? Maybe split the file to chunks ? Maybe streaming ?


Thank you.


-
How to install ffmpeg on a Windows Dockerhub image ?
18 janvier, par Youssef KharoufiI have a program that executes a ffmpeg command to a video input, copies this video and pastes is in an output directory.


Here is my code in case you would want to duplicate it :


using Renderer.Models;
using System;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;

public class Program
{
 public static async Task Main(string[] args)
 {
 var result = new DockerTaskResult();
 try
 {
 // Path to the JSON input file
 string jsonInputPath = @"C:\Users\ykharoufi\source\repos\Renderer\Renderer\Json\task.json";

 // Check if the JSON file exists
 if (!File.Exists(jsonInputPath))
 {
 throw new FileNotFoundException($"JSON input file not found at path: {jsonInputPath}");
 }

 // Read the JSON content
 string jsonContent = File.ReadAllText(jsonInputPath);

 try
 {
 // Deserialize the JSON into a DockerTask object
 DockerTask task = JsonSerializer.Deserialize<dockertask>(jsonContent);
 if (task == null)
 {
 throw new Exception("Failed to deserialize the task from JSON.");
 }

 // Validate the input paths
 if (string.IsNullOrEmpty(task.InputFileRepoPath) || !File.Exists(task.InputFileRepoPath))
 {
 throw new Exception($"Input file path is invalid or does not exist: {task.InputFileRepoPath}");
 }

 if (string.IsNullOrEmpty(task.OutputFileRepoPath) || !Directory.Exists(task.OutputFileRepoPath))
 {
 throw new Exception($"Output directory path is invalid or does not exist: {task.OutputFileRepoPath}");
 }

 // Initialize the Docker worker and run the task
 var worker = new DockerWorker();
 var success = await worker.RunDockerTaskAsync(task);

 if (success.Success)
 {
 result.Success = true;
 result.Message = "Command executed successfully!";

 // Check the output directory for files
 if (Directory.Exists(task.OutputFileRepoPath))
 {
 result.OutputFiles = Directory.GetFiles(task.OutputFileRepoPath);
 }
 }
 else
 {
 result.Success = false;
 result.Message = "Failed to execute the command.";
 result.ErrorDetails = success.ErrorDetails;
 }
 }
 catch (JsonException)
 {
 // Handle invalid JSON format
 result.Success = false;
 result.Message = "Invalid JSON format.";
 result.ErrorDetails = "Invalid data entry";
 }
 }
 catch (Exception ex)
 {
 result.Success = false;
 result.Message = "An error occurred during execution.";
 result.ErrorDetails = ex.Message;
 }
 finally
 {
 // Serialize the result to JSON and write to console
 string outputJson = JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true });
 Console.WriteLine(outputJson);
 }
 }
}

 using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using Docker.DotNet;
using Docker.DotNet.Models;
using Renderer.Models;

public class DockerWorker
{
 private readonly DockerClient _dockerClient;

 public DockerWorker()
 {
 Console.WriteLine("Initializing Docker client...");
 _dockerClient = new DockerClientConfiguration(
 new Uri("npipe://./pipe/docker_engine")) // Windows Docker URI
 .CreateClient();
 Console.WriteLine("Docker client initialized.");
 }

 public async Task<dockertaskresult> RunDockerTaskAsync(DockerTask task)
 {
 var result = new DockerTaskResult();

 try
 {
 Console.WriteLine("Starting Docker task...");
 Console.WriteLine($"Image: {task.ImageNaming}");
 Console.WriteLine($"Container: {task.ContainerNaming}");
 Console.WriteLine($"Input Path: {task.InputFileRepoPath}");
 Console.WriteLine($"Output Path: {task.OutputFileRepoPath}");
 Console.WriteLine($"Command: {task.CommandDef}");

 // Ensure the Docker image exists
 Console.WriteLine("Checking if Docker image exists...");
 var imageCheckResult = await EnsureImageExists(task.ImageNaming);
 if (!imageCheckResult.Success)
 {
 result.Success = false;
 result.Message = imageCheckResult.Message;
 result.ErrorDetails = imageCheckResult.ErrorDetails;
 return result;
 }
 Console.WriteLine("Docker image verified.");

 // Determine platform
 var platform = await GetImagePlatform(task.ImageNaming);
 Console.WriteLine($"Detected image platform: {platform}");

 // Translate paths
 string inputVolume, outputVolume;
 if (platform == "linux")
 {
 inputVolume = $"{task.InputFileRepoPath.Replace("C:\\", "/mnt/c/").Replace("\\", "/")}:/app/input";
 outputVolume = $"{task.OutputFileRepoPath.Replace("C:\\", "/mnt/c/").Replace("\\", "/")}:/app/output";
 }
 else if (platform == "windows")
 {
 string inputDir = Path.GetFullPath(Path.GetDirectoryName(task.InputFileRepoPath)).TrimEnd('\\');
 string outputDir = Path.GetFullPath(task.OutputFileRepoPath).TrimEnd('\\');

 if (!Directory.Exists(inputDir))
 {
 throw new Exception($"Input directory does not exist: {inputDir}");
 }
 if (!Directory.Exists(outputDir))
 {
 throw new Exception($"Output directory does not exist: {outputDir}");
 }

 inputVolume = $"{inputDir}:C:\\app\\input";
 outputVolume = $"{outputDir}:C:\\app\\output";

 Console.WriteLine($"Input volume: {inputVolume}");
 Console.WriteLine($"Output volume: {outputVolume}");
 }
 else
 {
 throw new Exception($"Unsupported platform: {platform}");
 }

 // Create container
 Console.WriteLine("Creating Docker container...");
 var containerResponse = await _dockerClient.Containers.CreateContainerAsync(new CreateContainerParameters
 {
 Image = task.ImageNaming,
 Name = task.ContainerNaming,
 HostConfig = new HostConfig
 {
 Binds = new List<string> { inputVolume, outputVolume },
 AutoRemove = true
 },
 Cmd = new[] { platform == "linux" ? "bash" : "cmd.exe", "/c", task.CommandDef }
 });

 if (string.IsNullOrEmpty(containerResponse.ID))
 {
 throw new Exception("Failed to create Docker container.");
 }
 Console.WriteLine($"Container created with ID: {containerResponse.ID}");

 // Start container
 Console.WriteLine("Starting container...");
 bool started = await _dockerClient.Containers.StartContainerAsync(containerResponse.ID, new ContainerStartParameters());
 if (!started)
 {
 throw new Exception($"Failed to start container: {task.ContainerNaming}");
 }

 // Wait for container to finish
 Console.WriteLine("Waiting for container to finish...");
 var waitResponse = await _dockerClient.Containers.WaitContainerAsync(containerResponse.ID);

 if (waitResponse.StatusCode != 0)
 {
 Console.WriteLine($"Container exited with error code: {waitResponse.StatusCode}");
 await FetchContainerLogs(containerResponse.ID);
 throw new Exception($"Container exited with non-zero status code: {waitResponse.StatusCode}");
 }

 // Fetch logs
 Console.WriteLine("Fetching container logs...");
 await FetchContainerLogs(containerResponse.ID);

 result.Success = true;
 result.Message = "Docker task completed successfully.";
 return result;
 }
 catch (Exception ex)
 {
 Console.WriteLine($"Error: {ex.Message}");
 result.Success = false;
 result.Message = "An error occurred during execution.";
 result.ErrorDetails = ex.Message;
 return result;
 }
 }

 private async Task<string> GetImagePlatform(string imageName)
 {
 try
 {
 Console.WriteLine($"Inspecting Docker image: {imageName}...");
 var imageDetails = await _dockerClient.Images.InspectImageAsync(imageName);
 Console.WriteLine($"Image platform: {imageDetails.Os}");
 return imageDetails.Os.ToLower();
 }
 catch (Exception ex)
 {
 throw new Exception($"Failed to inspect image: {ex.Message}");
 }
 }

 private async Task<dockertaskresult> EnsureImageExists(string imageName)
 {
 var result = new DockerTaskResult();
 try
 {
 Console.WriteLine($"Pulling Docker image: {imageName}...");
 await _dockerClient.Images.CreateImageAsync(
 new ImagesCreateParameters { FromImage = imageName, Tag = "latest" },
 null,
 new Progress<jsonmessage>()
 );
 result.Success = true;
 result.Message = "Docker image is available.";
 }
 catch (Exception ex)
 {
 result.Success = false;
 result.Message = $"Failed to pull Docker image: {imageName}";
 result.ErrorDetails = ex.Message;
 }
 return result;
 }

 private async Task FetchContainerLogs(string containerId)
 {
 try
 {
 Console.WriteLine($"Fetching logs for container: {containerId}...");
 var logs = await _dockerClient.Containers.GetContainerLogsAsync(
 containerId,
 new ContainerLogsParameters { ShowStdout = true, ShowStderr = true });

 using (var reader = new StreamReader(logs))
 {
 string logLine;
 while ((logLine = await reader.ReadLineAsync()) != null)
 {
 Console.WriteLine(logLine);
 }
 }
 }
 catch (Exception ex)
 {
 Console.WriteLine($"Failed to fetch logs: {ex.Message}");
 }
 }
}

 {
 "ImageNaming": "khuser/windowsimage:latest",
 "ContainerNaming": "custom-worker-container",
 "InputFileRepoPath": "C:/Users/user/source/repos/Renderer/Renderer/wwwroot/audio.mp4",
 "OutputFileRepoPath": "C:/Users/user/Desktop/output/",
 "CommandDef": "ffmpeg -i C:\\app\\input\\audio.mp4 -c copy C:\\app\\output\\copiedAudio.mp4"
</jsonmessage></dockertaskresult></string></string></dockertaskresult></dockertask>


}. My problem is what I get in the output of my program :
Initializing Docker client... Docker client initialized. Starting Docker task... Image: khyoussef/windowsimage:latest Container: custom-worker-container Input Path: C:/Users/ykharoufi/source/repos/Renderer/Renderer/wwwroot/audio.mp4 Output Path: C:/Users/ykharoufi/Desktop/output/ Command: ffmpeg -i C:\app\input\audio.mp4 -c copy C:\app\output\copiedAudio.mp4 Checking if Docker image exists... Pulling Docker image: khyoussef/windowsimage:latest... Docker image verified. Inspecting Docker image: khyoussef/windowsimage:latest... Image platform: windows Detected image platform: windows Input volume: C:\Users\ykharoufi\source\repos\Renderer\Renderer\wwwroot:C:\app\input Output volume: C:\Users\ykharoufi\Desktop\output:C:\app\output Creating Docker container... Container created with ID: 1daca99b3c76bc8c99c1aed7d2c546ae75aedd9aa1feb0f5002e54769390248e Starting container... Waiting for container to finish... Container exited with error code: 1 Fetching logs for container: 1daca99b3c76bc8c99c1aed7d2c546ae75aedd9aa1feb0f5002e54769390248e... @'ffmpeg' is not recognized as an internal or external command, !operable program or batch file. Error: Container exited with non-zero status code: 1 { "Success": false, "Message": "Failed to execute the command.", "ErrorDetails": "Container exited with non-zero status code: 1", "OutputFiles": null }
, This is the Dockerfile I am working with :

`# Use Windows Server Core as the base image
FROM mcr.microsoft.com/windows/server:ltsc2022

# Set the working directory
WORKDIR /app

# Install required tools (FFmpeg and Visual C++ Redistributable)
RUN powershell -Command \
 $ErrorActionPreference = 'Stop'; \
 # Install Visual C++ Redistributable
 Invoke-WebRequest -Uri https://aka.ms/vs/16/release/vc_redist.x64.exe -OutFile vc_redist.x64.exe; \
 Start-Process -FilePath vc_redist.x64.exe -ArgumentList '/install', '/quiet', '/norestart' -NoNewWindow -Wait; \
 Remove-Item -Force vc_redist.x64.exe; \
 # Download FFmpeg
 Invoke-WebRequest -Uri https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-n7.1-latest-win64-gpl-7.1.zip -OutFile ffmpeg.zip; \
 # Extract FFmpeg
 Expand-Archive -Path ffmpeg.zip -DestinationPath C:\ffmpeg; \
 Remove-Item -Force ffmpeg.zip; \
 # Debug step: Verify FFmpeg extraction
 Write-Output "FFmpeg extracted to C:\\ffmpeg"; \
 dir C:\ffmpeg; \
 dir C:\ffmpeg\ffmpeg-n7.1-latest-win64-gpl-7.1\bin

# Add FFmpeg to PATH permanently
ENV PATH="C:\\ffmpeg\\ffmpeg-n7.1-latest-win64-gpl-7.1\\bin;${PATH}"

# Verify FFmpeg installation
RUN ["cmd", "/S", "/C", "ffmpeg -version"]

# Copy required files to the container
COPY ./ /app/

# Default to a PowerShell session
CMD ["C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "-NoExit"]
`



. I did build it using this command : docker build -t khuser/windowsimage:latest -f Dockerfile .


-
Java uses FFmpegRecoder to encode frames into H264 streams
5 septembre 2024, par zhang1973I want to obtain the Frame from the video stream, process it, use FFmpegRecoder to encode it into an H264 stream, and transmit it to the front-end. But I found that the AVPacket obtained directly using grabber.grabAVPacket can be converted into H264 stream and played normally. The H264 stream encoded using FFmpegRecoder cannot be played.


Here is my Code :


private FFmpegFrameRecorder recorder;
 private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();;
 private boolean createRecoder(Frame frame){
 recorder = new FFmpegFrameRecorder(outputStream, frame.imageWidth, frame.imageHeight);
 recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
 recorder.setFormat("h264"); //"h264"); //
 recorder.setFrameRate(30);
 recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
 recorder.setVideoBitrate(4000 * 1000); // 设置比特率为4000 kbps
 recorder.setVideoOption("preset", "ultrafast"); // 设置编码器预设,"ultrafast"是最快的,"veryslow"是最慢但质量最好
 recorder.setAudioChannels(0);

 try {
 recorder.start();
 return recorderStatus = true;
 } catch (org.bytedeco.javacv.FrameRecorder.Exception e1) {
 log.info("启动转码录制器失败", e1);
 MediaService.cameras.remove(cameraDto.getMediaKey());
 e1.printStackTrace();
 }

 return recorderStatus = false;
 }

 private boolean slow = false;
 protected void transferStream2H264() throws FFmpegFrameGrabber.Exception {

 // 初始化和拉去图像的方法
 log.info(" create grabber ");
 if (!createGrabber()) {
 log.error(" == > ");
 return;
 }
 transferFlag = true;

 if(!createRecoder(grabber.grab())){
 return;
 }

 try {
 grabber.flush();
 } catch (Exception e) {
 log.info("清空拉流器缓存失败", e);
 e.printStackTrace();
 }

 if (header == null) {
 header = bos.toByteArray();
 slow = true;
// System.out.println("Header1");
// System.out.println(header);
 bos.reset();
 }else{
 System.out.println("Header2");
 System.out.println(header);
 }

 running = true;

 // 事实更新所有的连接数
 listenClient();

 long startTime = 0;
 long videoTS = 0;

 for (; running && grabberStatus;) {
 try {
 if (transferFlag) {
 long startGrab = System.currentTimeMillis();
 //视频采集器
// AVPacket pkt = grabber.grabPacket();
 Frame frame = grabber.grab();
 recorder.record(frame);
 byte[] videoData = outputStream.toByteArray();
 if ((System.currentTimeMillis() - startGrab) > 5000) {
 log.info("\r\n{}\r\n视频流网络异常>>>", cameraDto.getUrl());
 closeMedia();
 break;
 }

 videoTS = 1000 * (System.currentTimeMillis() - startTime);


 if (startTime == 0) {
 startTime = System.currentTimeMillis();
 }
 videoTS = 1000 * (System.currentTimeMillis() - startTime);

 byte[] rbuffer = videoData;
 readSize = videoData.length;

 if(spsdata == null || ppsdata == null){
 movePos = 0;
 lastPos = 0;
 isNewPack = true;
 while(movePos < readSize){
 if (rbuffer[movePos] == 0 && rbuffer[movePos + 1] == 0 && rbuffer[movePos + 2] == 1) {
 findCode = true;
 skipLen = 3;
 mCurFrameFirstByte = (int)(0xff & rbuffer[movePos + skipLen]);
 } else if (rbuffer[movePos] == 0 && rbuffer[movePos + 1] == 0 && rbuffer[movePos + 2] == 0 && rbuffer[movePos + 3] == 1) {
 findCode = true;
 skipLen = 4;
 mCurFrameFirstByte = (int)(0xff & rbuffer[movePos + skipLen]);
 } else {
 skipLen = 1;
 }

 if(!isFirstFind && isNewPack && findCode){
 mFrameFirstByte = mCurFrameFirstByte;
 findCode = false;
 isNewPack = false;
 mNaluType = mFrameFirstByte & 0x1f;
 if(mNaluType != MediaConstant.NALU_TYPE_SEI &&
 mNaluType != MediaConstant.NALU_TYPE_SPS &&
 mNaluType != MediaConstant.NALU_TYPE_PPS &&
 mNaluType != MediaConstant.NALU_TYPE_IDR){
 startCounter++;
 break;
 }
 }

 if(isFirstFind){
 isFirstFind = false;
 findCode = false;
 mFrameFirstByte = mCurFrameFirstByte;
 }

 if(findCode){
 startCounter++;
 mNaluType = mFrameFirstByte & 0x1f;

 findCode = false;
 mFrameLen = (movePos - lastPos);
 if(mNaluType == MediaConstant.NALU_TYPE_IDR){
 mFrameLen = readSize - movePos;
 }

 if(mNaluType != MediaConstant.NALU_TYPE_SEI &&
 mNaluType != MediaConstant.NALU_TYPE_SPS &&
 mNaluType != MediaConstant.NALU_TYPE_PPS &&
 mNaluType != MediaConstant.NALU_TYPE_IDR){
 System.out.println(" one packe many frames ---> type: " + mNaluType + " jump out ");
 break;
 }
 if(mNaluType == MediaConstant.NALU_TYPE_SPS){
 if(null == spsdata){
 spsdata = new byte[mFrameLen];
 System.arraycopy(rbuffer, lastPos, spsdata, 0, mFrameLen);
 }
 }
 if(mNaluType == MediaConstant.NALU_TYPE_PPS){

 if(null == ppsdata){
 ppsdata = new byte[mFrameLen];
 System.arraycopy(rbuffer, lastPos, ppsdata, 0, mFrameLen);
 }
 }

 lastPos = movePos;
 mFrameFirstByte = mCurFrameFirstByte;
 mNaluType = mFrameFirstByte & 0x1f;
 if(mNaluType == MediaConstant.NALU_TYPE_IDR){
 mFrameLen = readSize - movePos;
 startCounter++;

 break;
 }
 }

 movePos += skipLen;
 isNewPack = false;
 }
 }

 sendFrameData(rbuffer);
// }
// av_packet_unref(pkt);
// }

// }
 } else {
 }
 } catch (Exception e) {
 grabberStatus = false;
 MediaService.cameras.remove(cameraDto.getMediaKey());
 } catch (FFmpegFrameRecorder.Exception e) {
 throw new RuntimeException(e);
 }
 }

 try {
 grabber.close();
 bos.close();
 } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
 e.printStackTrace();
 } catch (Exception e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 } finally {
 closeMedia();
 }
 log.info("关闭媒体流-javacv,{} ", cameraDto.getUrl());
 }