2

我正在以编程方式进行一些转码并创建了一个 mpeg4 视频。问题是它不能在 Android 的原生播放器(Galaxy Nexus 和 Nexus S)上播放。请参阅下面的错误和编解码器详细信息。

我有播放成功的文件和播放失败的文件。Android无法创建媒体播放器的这个文件到底有什么问题?

问题:为什么没有播放文件?

更多信息:转码是使用 iPhone 创建的。伪代码:AVAssetExportSession->>exportAsynchronouslyWithCompletionHandler(AVFileTypeMPEG4)

这是视频的编解码器: 视频编解码器详细信息

这是错误:

02-14 12:39:33.243: E/MediaPlayerService(132):   error: -2147483648
02-14 12:39:33.243: E/MediaPlayer(25598): Unable to to create media player
02-14 12:39:33.251: W/VideoView(25598): Unable to open content: file:///storage/sdcard0/Download/IMG_0002.MOV-st.mp4
02-14 12:39:33.251: W/VideoView(25598): java.io.IOException: setDataSourceFD failed.: status=0x80000000
02-14 12:39:33.251: W/VideoView(25598):     at android.media.MediaPlayer.setDataSource(Native Method)
02-14 12:39:33.251: W/VideoView(25598):     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:976)
02-14 12:39:33.251: W/VideoView(25598):     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:955)
02-14 12:39:33.251: W/VideoView(25598):     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:918)
02-14 12:39:33.251: W/VideoView(25598):     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:870)
02-14 12:39:33.251: W/VideoView(25598):     at android.widget.VideoView.openVideo(VideoView.java:238)
02-14 12:39:33.251: W/VideoView(25598):     at android.widget.VideoView.access$2000(VideoView.java:52)
02-14 12:39:33.251: W/VideoView(25598):     at android.widget.VideoView$6.surfaceCreated(VideoView.java:492)
02-14 12:39:33.251: W/VideoView(25598):     at android.view.SurfaceView.updateWindow(SurfaceView.java:569)
02-14 12:39:33.251: W/VideoView(25598):     at android.view.SurfaceView.setVisibility(SurfaceView.java:249)
02-14 12:39:33.251: W/VideoView(25598):     at com.android.gallery3d.app.MoviePlayer$4.run(MoviePlayer.java:147)
02-14 12:39:33.251: W/VideoView(25598):     at android.os.Handler.handleCallback(Handler.java:725)
02-14 12:39:33.251: W/VideoView(25598):     at android.os.Handler.dispatchMessage(Handler.java:92)
02-14 12:39:33.251: W/VideoView(25598):     at android.os.Looper.loop(Looper.java:137)
02-14 12:39:33.251: W/VideoView(25598):     at android.app.ActivityThread.main(ActivityThread.java:5039)
02-14 12:39:33.251: W/VideoView(25598):     at java.lang.reflect.Method.invokeNative(Native Method)
02-14 12:39:33.251: W/VideoView(25598):     at java.lang.reflect.Method.invoke(Method.java:511)
02-14 12:39:33.251: W/VideoView(25598):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-14 12:39:33.251: W/VideoView(25598):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-14 12:39:33.251: W/VideoView(25598):     at dalvik.system.NativeStart.main(Native Method)
02-14 12:39:33.251: D/VideoView(25598): Error: 1,0
4

1 回答 1

1

在遇到同样的问题后,我做了很多挖掘并尝试了许多不同的技术来解决这个问题。许多其他同类型的 SO 问题都得到了“只需将 iPhone 创建的 .MOV 文件保存为 .mp4”的响应。从理论上讲,这会起作用,因为它们都是容器,但是,这(至少对我而言)会导致与此处提到的相同的“无法打开内容”错误(以及在我测试过的每台设备上)。我的解决方案确实最终使用了 AVAssetExportSession。这是我使用的代码:

AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:self.sharingMovieUrl options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) {
     AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];    
    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"temp3.mp4"];    
    exportSession.outputURL = [NSURL fileURLWithPath:filePath];    
    exportSession.outputFileType = AVFileTypeMPEG4;
    [exportSession exportAsynchronouslyWithCompletionHandler:^{        
        switch ([exportSession status]) {

            case AVAssetExportSessionStatusFailed:
                //If this fails, it might be because the temorary
                //files weren't cleaned and this isn't overwriting
                //the temporary filename
                NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
                //Perform any failed logic                
                break;                
            case AVAssetExportSessionStatusCancelled:                
                NSLog(@"Export canceled");
                //Perform any cancel logic                
                break;                
            default:
                //This should have been a success                                
                //File should be saved at filePath
                //Upload file from here
                break;                
        }        
    }];
}
于 2014-02-07T18:35:45.497 回答