Android将视频保存到文件

Posted

技术标签:

【中文标题】Android将视频保存到文件【英文标题】:Android saving a video to a file 【发布时间】:2015-01-17 22:58:07 【问题描述】:

我正在设计一个具有媒体功能的应用程序,其中之一是视频捕获。我正在使用对相机的默认调用,而不是创建自己的相机。我遇到的问题是,在捕获视频后,它不会保存到我指定的视频文件中,但到目前为止,我测试过的这个问题只发生在使用相机应用程序的三星手机上。如果我在三星手机或其他公司的手机上使用谷歌相机,它工作正常。这是三星手机的已知错误还是我做错了什么?如果是,有解决办法吗?

这是我的视频处理程序。

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)

【问题讨论】:

您是否收到错误消息?您可以发布异常堆栈跟踪吗? 【参考方案1】:

我解决了我的问题。基本上我发现有人这么说。

相机应用不要求遵循 ACTION_IMAGE_CAPTURE 或 ACTION_VIDEO_CAPTURE 的规则。有些会尊重特定请求的输出位置。有些人不会,并且会返回他们选择将图像/视频存储在 Uri 中的位置,该 Uri 包含在 onActivityResult() 上传递的结果 Intent 中。有些可能完全损坏,并且不会告诉您图像/视频的存储位置,即使存储了一个。

然后我在另一个帖子中发现我必须手动检索它。

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 是您要以字符串格式保存文件的路径。

【讨论】:

【参考方案2】:

您使用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();

tl;dr

我认为这会解决你的问题

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

【讨论】:

实例化后考虑 video.mkdirs()。 我现在无法测试解决方案,但我会尽快通知您。 我尝试创建一个常规文件,但仍然无法正常工作。

以上是关于Android将视频保存到文件的主要内容,如果未能解决你的问题,请参考以下文章

自动将视频文件保存到 Android SD 卡

Android - 将视频从摄像头流式传输到另一个Android设备

Android 11 拍照+录制视频保存到外部共享区域

在android中反转视频

将视频保存为输入而不是android中的相机

Android - 将原始资产中的文件保存到外部存储以供其他应用访问,导致找不到内容根异常