使用SharpAvi转图片为视频后,Windows Media Player播放仅黑屏1秒
Hey there, let's figure out why your AVI file only shows a 1-second black screen in Windows Media Player. From the code snippet you shared, there are a few common pitfalls with SharpAvi that could be causing this. Let's break them down one by one:
Common Causes & Fixes
1. Incomplete Video Stream Configuration
Your code cuts off at var stream = writer.AddVideoStream(...)—this is critical! SharpAvi requires you to specify the pixel format and encoding type explicitly. For example, if you're using raw video (which is easiest for compatibility), you need to define the pixel format as PixelFormat.Bgr32 (the format SharpAvi expects by default). If you skip this, the stream might be configured incorrectly, leading to unreadable frames.
2. Base64 to Frame Conversion Errors
Your frames list is Base64 strings—you need to correctly decode these into a Bitmap (or byte[] in the right pixel format) before writing to the stream. A common mistake is not converting the decoded image to BGR32, which is required for SharpAvi's video streams. If the pixel format doesn't match, the frames won't render properly.
3. Missing Frame Writing Logic
If you're not actually looping through your frames list and calling stream.WriteFrame(...) for each one, your video will have no content—just a blank placeholder that plays for 1 second (since WMP might recognize the file structure but no frame data).
4. Improper File Closure
SharpAvi's AviWriter needs to be properly closed to finalize the AVI file's index and headers. If you forget to call writer.Close() or don't wrap it in a using statement, the file will be corrupted, leading to playback issues.
5. Framerate vs. Frame Count Mismatch
You set FramesPerSecond = 2, but if you only write 1 frame, the video will only last 0.5 seconds—WMP might display this as a quick black screen. Make sure you're writing all your frames to the stream.
Fixed Example Code
Here's a complete, working version of your code that addresses these issues:
private void CreateMovie(List<string> frames) { int width = 320; int height = 240; var frameRate = 2; // Use 'using' to ensure proper disposal/closure using (var writer = new AviWriter("C:\\test.avi") { FramesPerSecond = frameRate, EmitIndex1 = true }) { // Add video stream with explicit BGR32 pixel format (raw video for compatibility) var stream = writer.AddVideoStream(width, height, frameRate); stream.Codec = KnownFourCCs.Codecs.Uncompressed; // Raw video, no compression foreach (var base64Frame in frames) { // Decode Base64 to byte array byte[] imageBytes = Convert.FromBase64String(base64Frame); // Convert to Bitmap using (var ms = new MemoryStream(imageBytes)) using (var bitmap = new Bitmap(ms)) { // Convert Bitmap to BGR32 pixel format (required by SharpAvi) using (var bgrBitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb)) { using (var g = Graphics.FromImage(bgrBitmap)) { g.DrawImage(bitmap, 0, 0, width, height); } // Lock bitmap data to get raw bytes var bitmapData = bgrBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb); try { // Write frame to stream stream.WriteFrame(true, bitmapData.Scan0, bitmapData.Stride * height); } finally { bgrBitmap.UnlockBits(bitmapData); } } } } } // 'using' will automatically close the writer here }
Additional Tips
- If you want to use compression (like MJPEG), replace
KnownFourCCs.Codecs.UncompressedwithKnownFourCCs.Codecs.Mjpeg—but make sure Windows Media Player has the necessary codec installed. - Verify that your Base64 strings are valid image data (you can test by decoding one to an image file manually).
- After generating the AVI, try playing it with VLC first—if it plays there, the issue might be WMP's codec support, not your code.
内容的提问来源于stack exchange,提问作者Jose Relloso

