1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.gallery3d.util;
18 
19 import android.content.ContentResolver;
20 import android.content.ContentValues;
21 import android.database.Cursor;
22 import android.media.MediaMetadataRetriever;
23 import android.net.Uri;
24 import android.os.Environment;
25 import android.provider.MediaStore.Video;
26 import android.provider.MediaStore.Video.VideoColumns;
27 
28 import com.android.gallery3d.filtershow.tools.SaveImage.ContentResolverQueryCallback;
29 
30 import java.io.File;
31 import java.text.SimpleDateFormat;
32 import java.util.Date;
33 
34 public class SaveVideoFileUtils {
35     // This function can decide which folder to save the video file, and generate
36     // the needed information for the video file including filename.
getDstMp4FileInfo(String fileNameFormat, ContentResolver contentResolver, Uri uri, String defaultFolderName)37     public static SaveVideoFileInfo getDstMp4FileInfo(String fileNameFormat,
38             ContentResolver contentResolver, Uri uri, String defaultFolderName) {
39         SaveVideoFileInfo dstFileInfo = new SaveVideoFileInfo();
40         // Use the default save directory if the source directory cannot be
41         // saved.
42         dstFileInfo.mDirectory = getSaveDirectory(contentResolver, uri);
43         if ((dstFileInfo.mDirectory == null) || !dstFileInfo.mDirectory.canWrite()) {
44             dstFileInfo.mDirectory = new File(Environment.getExternalStorageDirectory(),
45                     BucketNames.DOWNLOAD);
46             dstFileInfo.mFolderName = defaultFolderName;
47         } else {
48             dstFileInfo.mFolderName = dstFileInfo.mDirectory.getName();
49         }
50         dstFileInfo.mFileName = new SimpleDateFormat(fileNameFormat).format(
51                 new Date(System.currentTimeMillis()));
52 
53         dstFileInfo.mFile = new File(dstFileInfo.mDirectory, dstFileInfo.mFileName + ".mp4");
54         return dstFileInfo;
55     }
56 
querySource(ContentResolver contentResolver, Uri uri, String[] projection, ContentResolverQueryCallback callback)57     private static void querySource(ContentResolver contentResolver, Uri uri,
58             String[] projection, ContentResolverQueryCallback callback) {
59         Cursor cursor = null;
60         try {
61             cursor = contentResolver.query(uri, projection, null, null, null);
62             if ((cursor != null) && cursor.moveToNext()) {
63                 callback.onCursorResult(cursor);
64             }
65         } catch (Exception e) {
66             // Ignore error for lacking the data column from the source.
67         } finally {
68             if (cursor != null) {
69                 cursor.close();
70             }
71         }
72     }
73 
getSaveDirectory(ContentResolver contentResolver, Uri uri)74     private static File getSaveDirectory(ContentResolver contentResolver, Uri uri) {
75         final File[] dir = new File[1];
76         querySource(contentResolver, uri,
77                 new String[] { VideoColumns.DATA },
78                 new ContentResolverQueryCallback() {
79             @Override
80             public void onCursorResult(Cursor cursor) {
81                 dir[0] = new File(cursor.getString(0)).getParentFile();
82             }
83         });
84         return dir[0];
85     }
86 
87 
88     /**
89      * Insert the content (saved file) with proper video properties.
90      */
insertContent(SaveVideoFileInfo mDstFileInfo, ContentResolver contentResolver, Uri uri )91     public static Uri insertContent(SaveVideoFileInfo mDstFileInfo,
92             ContentResolver contentResolver, Uri uri ) {
93         long nowInMs = System.currentTimeMillis();
94         long nowInSec = nowInMs / 1000;
95         final ContentValues values = new ContentValues(13);
96         values.put(Video.Media.TITLE, mDstFileInfo.mFileName);
97         values.put(Video.Media.DISPLAY_NAME, mDstFileInfo.mFile.getName());
98         values.put(Video.Media.MIME_TYPE, "video/mp4");
99         values.put(Video.Media.DATE_TAKEN, nowInMs);
100         values.put(Video.Media.DATE_MODIFIED, nowInSec);
101         values.put(Video.Media.DATE_ADDED, nowInSec);
102         values.put(Video.Media.DATA, mDstFileInfo.mFile.getAbsolutePath());
103         values.put(Video.Media.SIZE, mDstFileInfo.mFile.length());
104         int durationMs = retriveVideoDurationMs(mDstFileInfo.mFile.getPath());
105         values.put(Video.Media.DURATION, durationMs);
106         // Copy the data taken and location info from src.
107         String[] projection = new String[] {
108                 VideoColumns.DATE_TAKEN,
109                 VideoColumns.LATITUDE,
110                 VideoColumns.LONGITUDE,
111                 VideoColumns.RESOLUTION,
112         };
113 
114         // Copy some info from the source file.
115         querySource(contentResolver, uri, projection,
116                 new ContentResolverQueryCallback() {
117                 @Override
118                     public void onCursorResult(Cursor cursor) {
119                         long timeTaken = cursor.getLong(0);
120                         if (timeTaken > 0) {
121                             values.put(Video.Media.DATE_TAKEN, timeTaken);
122                         }
123                         double latitude = cursor.getDouble(1);
124                         double longitude = cursor.getDouble(2);
125                         // TODO: Change || to && after the default location
126                         // issue is
127                         // fixed.
128                         if ((latitude != 0f) || (longitude != 0f)) {
129                             values.put(Video.Media.LATITUDE, latitude);
130                             values.put(Video.Media.LONGITUDE, longitude);
131                         }
132                         values.put(Video.Media.RESOLUTION, cursor.getString(3));
133 
134                     }
135                 });
136 
137         return contentResolver.insert(Video.Media.EXTERNAL_CONTENT_URI, values);
138     }
139 
retriveVideoDurationMs(String path)140     public static int retriveVideoDurationMs(String path) {
141         int durationMs = 0;
142         // Calculate the duration of the destination file.
143         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
144         retriever.setDataSource(path);
145         String duration = retriever.extractMetadata(
146                 MediaMetadataRetriever.METADATA_KEY_DURATION);
147         if (duration != null) {
148             durationMs = Integer.parseInt(duration);
149         }
150         retriever.release();
151         return durationMs;
152     }
153 
154 }
155