转码的MPEG-4视频无法在Android的原生应用上播放

时间:2013-02-14 12:48:25

标签: android ios android-mediaplayer codec

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

我有成功播放的文件和无法播放的文件。 Android无法创建媒体播放器的此文件究竟出了什么问题?

问题:为什么不播放文件?

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

这是视频的编解码器: Video codec details

这是错误:

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

1 个答案:

答案 0 :(得分: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;                
        }        
    }];
}