求助:C#实现AVI文件帧解码编辑编码及AForgeNet报错解决
First: Resolve AForge.VFW Errors
1. Target x86 Architecture
AForge.VFW relies on 32-bit Video for Windows (VFW) APIs. Mismatched bitness is a common cause of access violation errors. To fix:
- Right-click your project → Properties → Build
- Set "Platform target" to x86
- Clean and rebuild the project
2. Install VFW-Compatible Codecs
The "Failed initializing decompressor" error means your system lacks a VFW decompressor for the AVI's codec.
- Install a codec pack with VFW support (ensure VFW components are included)
- Test with an uncompressed AVI first to rule out codec compatibility issues
3. Proper Resource Management
Use using statements to ensure AVIReader/AVIWriter are disposed correctly, preventing memory corruption:
using AForge.Video.VFW; using System.Drawing; private void ProcessAviWithAForge(string inputPath, string outputPath) { using (AVIReader reader = new AVIReader()) using (AVIWriter writer = new AVIWriter("MJPG")) // Use codec like "MJPG" or "Uncompressed" { reader.Open(inputPath); // Match output settings to input writer.FrameRate = reader.FrameRate; writer.Open(outputPath, reader.Width, reader.Height); Bitmap frame; while ((frame = reader.GetNextFrame()) != null) { // Custom modification logic ModifyBitmap(frame); // Write modified frame to output writer.AddFrame(frame); // Free frame memory frame.Dispose(); } reader.Close(); writer.Close(); } } private void ModifyBitmap(Bitmap bmp) { // Example: Draw a red rectangle on the frame using (Graphics g = Graphics.FromImage(bmp)) { g.DrawRectangle(Pens.Red, 10, 10, 50, 50); } }
4. Verify AVI Codec Compatibility
VFW doesn't support modern codecs like H.264 in AVI. Convert your input to a VFW-compatible format (e.g., MJPEG or uncompressed) using a tool like FFmpeg before processing.
Alternative: Use FFmpeg.AutoGen (Powerful & Modern)
If AForge's VFW limitations are too restrictive, FFmpeg supports nearly all video codecs. Here's a simplified outline:
Setup
- Install the
FFmpeg.AutoGenNuGet package - Download FFmpeg shared libraries (matching your project bitness) and place them in your output directory
Core Workflow
- Initialize FFmpeg libraries
- Open the input file and locate the video stream
- Initialize the decoder and read packets
- Decode packets to frames, convert to
Bitmapfor modification - Convert modified
Bitmapback to FFmpeg frames - Encode frames and write to the output file
Alternative: MediaToolkit (Simpler FFmpeg Wrapper)
For a user-friendly FFmpeg interface, use MediaToolkit:
Setup
- Install the
MediaToolkitNuGet package - Ensure FFmpeg binaries are in your system PATH or project directory
Example Code
using MediaToolkit; using MediaToolkit.Model; using MediaToolkit.Options; using System.Drawing; using System.Drawing.Imaging; private void ProcessAviWithMediaToolkit(string inputPath, string outputPath) { var inputFile = new MediaFile { Filename = inputPath }; var outputFile = new MediaFile { Filename = outputPath }; using (var engine = new Engine()) { engine.GetMetadata(inputFile); var fps = inputFile.Metadata.VideoData.Fps; var totalFrames = (int)(inputFile.Metadata.Duration.TotalSeconds * fps); // Extract and modify each frame for (int i = 0; i < totalFrames; i++) { var extractOpts = new ConversionOptions { Seek = TimeSpan.FromSeconds(i / (double)fps) }; var tempFrame = new MediaFile { Filename = $"temp_frame_{i}.png" }; engine.Convert(inputFile, tempFrame, extractOpts); // Modify frame Bitmap frame = new Bitmap(tempFrame.Filename); ModifyBitmap(frame); frame.Save($"modified_frame_{i}.png", ImageFormat.Png); frame.Dispose(); } // Combine modified frames back to video var encodeOpts = new ConversionOptions { VideoFrameRate = fps }; var modifiedFrames = Directory.GetFiles(Directory.GetCurrentDirectory(), "modified_frame_*.png"); engine.JoinMediaFiles(outputFile, encodeOpts, modifiedFrames); // Clean up temp files foreach (var file in modifiedFrames.Concat(Directory.GetFiles(".", "temp_frame_*.png"))) { File.Delete(file); } } }
内容的提问来源于stack exchange,提问作者jasonbb

