Android将视频保存到文件

3
我正在设计一个带有媒体功能的应用程序,其中之一是视频捕获。我使用默认的调用相机功能,而不是创建自己的相机。我的问题是,在捕捉视频后,它没有保存到我指定的视频文件中。但是,就我目前测试的情况来看,这个问题只发生在使用三星手机的原生相机应用时。如果我在三星手机上使用Google相机或另一家公司的手机则可以正常工作。这是否是三星手机已知的错误,还是我做错了什么?如果是已知问题,是否有解决方法?
这是我的videoHandler。
private void videoHandler() {
    Intent intent = new Intent( MediaStore.ACTION_VIDEO_CAPTURE );
    if ( intent.resolveActivity( getPackageManager() ) != null ) {
        File videoFile = null;
        try {
            videoFile = createVideoFile();
        } catch ( IOException e ) {
            System.out.println( "Error creating file." );
        }

        if ( videoFile != null ) {
            videoUri = Uri.fromFile( videoFile );
            intent.putExtra( MediaStore.EXTRA_OUTPUT, videoUri );
            intent.putExtra( MediaStore.EXTRA_VIDEO_QUALITY, 1 );
            intent.putExtra( MediaStore.EXTRA_SIZE_LIMIT, 15000000L );
            intent.putExtra( MediaStore.EXTRA_DURATION_LIMIT, 6 );
            startActivityForResult( intent, VIDEO_REQUEST_CODE );
        }
    }
}

它调用createVideoFile方法,在此处我预先为目标创建一个视频文件。
private File createVideoFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat( "yyyyMMdd_HHmmss" ).format( new Date() );
    String imageFileName = "MP4_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES );
    File video = File.createTempFile(
            imageFileName,  /* prefix */
            ".mp4",         /* suffix */
            storageDir      /* directory */
    );

    this.videoUri = Uri.fromFile( video );
    Intent mediaScanIntent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE );
    mediaScanIntent.setData( this.videoUri );
    this.sendBroadcast( mediaScanIntent );
    return video;
}

当我尝试在我的onActivityResult中调用videouri时,出现了以下错误:

01-17 16:37:23.254  27162-28145/com.example.kevinem.blitz E/ImageLoader﹕ /storage/emulated/0/Pictures/MP4_20150117_163704_-918353230.mp4: open failed: ENOENT (No such file or directory)
java.io.FileNotFoundException: /storage/emulated/0/Pictures/MP4_20150117_163704_-918353230.mp4: open failed: ENOENT (No such file or directory)
        at libcore.io.IoBridge.open(IoBridge.java:409)
        at java.io.FileInputStream.<init>(FileInputStream.java:78)
        at java.io.FileInputStream.<init>(FileInputStream.java:105)
        at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStreamFromFile(BaseImageDownloader.java:160)
        at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStream(BaseImageDownloader.java:88)
        at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.getImageStream(BaseImageDecoder.java:93)
        at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:73)
        at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:264)
        at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:237)
        at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:135)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:841)
 Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
        at libcore.io.Posix.open(Native Method)
        at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
        at libcore.io.IoBridge.open(IoBridge.java:393)

你是否遇到了错误?你能否提供异常堆栈跟踪信息? - Dave Swersky
2个回答

1

我解决了我的问题。基本上,我找到了有人这样说。

相机应用程序没有遵循ACTION_IMAGE_CAPTURE或ACTION_VIDEO_CAPTURE的规则的要求。有些应用程序会遵守特定的请求输出位置。有些不会,并且将返回包含在onActivityResult()中传递的结果Intent中的Uri中存储图像/视频的位置。有些可能完全失效,并且即使有一个存储,也不会告诉您图像/视频存储在哪里。

然后我在另一篇文章中发现我必须手动检索它。

if (resultCode == -1) {
        //create a MediaScanner to save the vid into the indicate path
        new MediaScannerConnectionClient() {
            private MediaScannerConnection msc = null;
            {
                msc = new MediaScannerConnection(
                        getApplicationContext(), this);
                msc.connect();
            }

            public void onMediaScannerConnected() {
                msc.scanFile(name_vid, null);
            }

            public void onScanCompleted(String path, Uri uri) {
                msc.disconnect();

            }
        };
        Toast.makeText(this,"Video saved succesfull",
                Toast.LENGTH_SHORT).show();
}

name_vid是您想以String格式保存文件的路径。


0

你使用 File.createTempFile( ) 有特别的原因吗?

使用给定的前缀和后缀生成文件名,在默认临时文件目录中创建一个空文件。调用此方法等效于调用 createTempFile(prefix, suffix, null)。

Files.createTempFile 方法提供了一种在临时文件目录中创建空文件的替代方法。由该方法创建的文件可能比此方法创建的文件具有更严格的访问权限,因此可能更适合安全敏感的应用程序。

不确定这是否产生了预期的结果。我建议查看此文档。

http://developer.android.com/reference/android/os/Environment.html#getExternalStoragePublicDirectory(java.lang.String)

特别是这一部分。
File path = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
File file = new File(path, "DemoPicture.jpg");
return file.exists();

简短概述:

我认为这将修复你的问题。

 File video = new File(storageDir,  imageFileName + ".mp4")

在实例化后考虑使用 video.mkdirs()。 - brthornbury
我现在无法测试解决方案,但我会尽快告诉你。 - danigh
我已经尝试过创建一个普通的文件,但仍然无法工作。 - danigh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接