transcode videos before sharing. change storage location
This commit is contained in:
		
							parent
							
								
									9b6ae6d75f
								
							
						
					
					
						commit
						66457c9f2e
					
				|  | @ -40,6 +40,7 @@ dependencies { | |||
|     compile 'org.whispersystems:axolotl-android:1.3.4' | ||||
|     compile 'com.makeramen:roundedimageview:2.2.0' | ||||
|     compile "com.wefika:flowlayout:0.4.1" | ||||
|     compile 'net.ypresto.androidtranscoder:android-transcoder:0.2.0' | ||||
| } | ||||
| 
 | ||||
| ext { | ||||
|  |  | |||
|  | @ -19,6 +19,8 @@ | |||
|         android:name="android.permission.READ_PHONE_STATE" | ||||
|         tools:node="remove" /> | ||||
| 
 | ||||
|     <uses-sdk tools:overrideLibrary="net.ypresto.androidtranscoder" /> | ||||
| 
 | ||||
|     <application | ||||
|         android:allowBackup="true" | ||||
|         android:icon="@drawable/ic_launcher" | ||||
|  |  | |||
|  | @ -71,7 +71,7 @@ public class FileBackend { | |||
| 	} | ||||
| 
 | ||||
| 	private void createNoMedia() { | ||||
| 		final File nomedia = new File(getConversationsFileDirectory()+".nomedia"); | ||||
| 		final File nomedia = new File(getConversationsDirectory("Files")+".nomedia"); | ||||
| 		if (!nomedia.exists()) { | ||||
| 			try { | ||||
| 				nomedia.createNewFile(); | ||||
|  | @ -82,7 +82,9 @@ public class FileBackend { | |||
| 	} | ||||
| 
 | ||||
| 	public void updateMediaScanner(File file) { | ||||
| 		if (file.getAbsolutePath().startsWith(getConversationsImageDirectory())) { | ||||
| 		String path = file.getAbsolutePath(); | ||||
| 		if (!path.startsWith(getConversationsDirectory("Files"))) { | ||||
| 			new File(Environment.getExternalStorageDirectory()+"/Conversations/.nomedia").delete(); | ||||
| 			Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); | ||||
| 			intent.setData(Uri.fromFile(file)); | ||||
| 			mXmppConnectionService.sendBroadcast(intent); | ||||
|  | @ -118,14 +120,16 @@ public class FileBackend { | |||
| 			file = new DownloadableFile(path); | ||||
| 		} else { | ||||
| 			String mime = message.getMimeType(); | ||||
| 			if (mime != null && mime.startsWith("image")) { | ||||
| 				file = new DownloadableFile(getConversationsImageDirectory() + path); | ||||
| 			if (mime != null && mime.startsWith("image/")) { | ||||
| 				file = new DownloadableFile(getConversationsDirectory("Images") + path); | ||||
| 			} else if (mime != null && mime.startsWith("video/")) { | ||||
| 				file = new DownloadableFile(getConversationsDirectory("Videos") + path); | ||||
| 			} else { | ||||
| 				file = new DownloadableFile(getConversationsFileDirectory() + path); | ||||
| 				file = new DownloadableFile(getConversationsDirectory("Files") + path); | ||||
| 			} | ||||
| 		} | ||||
| 		if (encrypted) { | ||||
| 			return new DownloadableFile(getConversationsFileDirectory() + file.getName() + ".pgp"); | ||||
| 			return new DownloadableFile(getConversationsDirectory("Files") + file.getName() + ".pgp"); | ||||
| 		} else { | ||||
| 			return file; | ||||
| 		} | ||||
|  | @ -154,21 +158,11 @@ public class FileBackend { | |||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	public String getConversationsFileDirectory() { | ||||
| 	public String getConversationsDirectory(final String type) { | ||||
| 		if (Config.ONLY_INTERNAL_STORAGE) { | ||||
| 			return mXmppConnectionService.getFilesDir().getAbsolutePath() + "/Files/"; | ||||
| 			return mXmppConnectionService.getFilesDir().getAbsolutePath()+"/"+type+"/"; | ||||
| 		} else { | ||||
| 			return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Conversations/"; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public String getConversationsImageDirectory() { | ||||
| 		if (Config.ONLY_INTERNAL_STORAGE) { | ||||
| 			return mXmppConnectionService.getFilesDir().getAbsolutePath()+"/Pictures/"; | ||||
| 		} else { | ||||
| 			return Environment.getExternalStoragePublicDirectory( | ||||
| 					Environment.DIRECTORY_PICTURES).getAbsolutePath() | ||||
| 					+ "/Conversations/"; | ||||
| 			return Environment.getExternalStorageDirectory() +"/Conversations/Media/Conversations "+type+"/"; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import android.os.Build; | |||
| import android.os.Bundle; | ||||
| import android.os.Environment; | ||||
| import android.os.IBinder; | ||||
| import android.os.ParcelFileDescriptor; | ||||
| import android.os.PowerManager; | ||||
| import android.os.PowerManager.WakeLock; | ||||
| import android.os.SystemClock; | ||||
|  | @ -37,11 +38,15 @@ import net.java.otr4j.session.Session; | |||
| import net.java.otr4j.session.SessionID; | ||||
| import net.java.otr4j.session.SessionImpl; | ||||
| import net.java.otr4j.session.SessionStatus; | ||||
| import net.ypresto.androidtranscoder.MediaTranscoder; | ||||
| import net.ypresto.androidtranscoder.format.MediaFormatStrategyPresets; | ||||
| 
 | ||||
| import org.openintents.openpgp.IOpenPgpService2; | ||||
| import org.openintents.openpgp.util.OpenPgpApi; | ||||
| import org.openintents.openpgp.util.OpenPgpServiceConnection; | ||||
| 
 | ||||
| import java.io.FileDescriptor; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.math.BigInteger; | ||||
| import java.security.SecureRandom; | ||||
| import java.security.cert.CertificateException; | ||||
|  | @ -59,6 +64,7 @@ import java.util.ListIterator; | |||
| import java.util.Locale; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.CopyOnWriteArrayList; | ||||
| import java.util.concurrent.ExecutionException; | ||||
| import java.util.concurrent.atomic.AtomicLong; | ||||
| 
 | ||||
| import de.duenndns.ssl.MemorizingTrustManager; | ||||
|  | @ -97,6 +103,7 @@ import eu.siacs.conversations.persistance.DatabaseBackend; | |||
| import eu.siacs.conversations.persistance.FileBackend; | ||||
| import eu.siacs.conversations.ui.SettingsActivity; | ||||
| import eu.siacs.conversations.ui.UiCallback; | ||||
| import eu.siacs.conversations.ui.UiInformableCallback; | ||||
| import eu.siacs.conversations.utils.ConversationsFileObserver; | ||||
| import eu.siacs.conversations.utils.CryptoHelper; | ||||
| import eu.siacs.conversations.utils.ExceptionHelper; | ||||
|  | @ -457,10 +464,10 @@ public class XmppConnectionService extends Service { | |||
| 		} | ||||
| 		message.setCounterpart(conversation.getNextCounterpart()); | ||||
| 		message.setType(Message.TYPE_FILE); | ||||
| 		final String path = getFileBackend().getOriginalPath(uri); | ||||
| 		mFileAddingExecutor.execute(new Runnable() { | ||||
| 			@Override | ||||
| 			public void run() { | ||||
| 
 | ||||
| 			private void processAsFile() { | ||||
| 				final String path = getFileBackend().getOriginalPath(uri); | ||||
| 				if (path != null) { | ||||
| 					message.setRelativeFilePath(path); | ||||
| 					getFileBackend().updateFileParams(message); | ||||
|  | @ -488,6 +495,72 @@ public class XmppConnectionService extends Service { | |||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			private void processAsVideo() throws FileNotFoundException { | ||||
| 				Log.d(Config.LOGTAG,"processing file as video"); | ||||
| 				message.setRelativeFilePath(message.getUuid() + ".mp4"); | ||||
| 				final DownloadableFile file = getFileBackend().getFile(message); | ||||
| 				file.getParentFile().mkdirs(); | ||||
| 				ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r"); | ||||
| 				FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); | ||||
| 				final ArrayList<Integer> progressTracker = new ArrayList<>(); | ||||
| 				final UiInformableCallback<Message> informableCallback; | ||||
| 				if (callback instanceof UiInformableCallback) { | ||||
| 					informableCallback = (UiInformableCallback<Message>) callback; | ||||
| 				} else { | ||||
| 					informableCallback = null; | ||||
| 				} | ||||
| 				MediaTranscoder.Listener listener = new MediaTranscoder.Listener() { | ||||
| 					@Override | ||||
| 					public void onTranscodeProgress(double progress) { | ||||
| 						int p = ((int) Math.round(progress * 100) / 20) * 20; | ||||
| 						if (!progressTracker.contains(p) && p != 100 && p != 0) { | ||||
| 							progressTracker.add(p); | ||||
| 							if (informableCallback != null) { | ||||
| 
 | ||||
| 								informableCallback.inform(getString(R.string.transcoding_video_progress, p)); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					@Override | ||||
| 					public void onTranscodeCompleted() { | ||||
| 						if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { | ||||
| 							getPgpEngine().encrypt(message, callback); | ||||
| 						} else { | ||||
| 							callback.success(message); | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					@Override | ||||
| 					public void onTranscodeCanceled() { | ||||
| 						processAsFile(); | ||||
| 					} | ||||
| 
 | ||||
| 					@Override | ||||
| 					public void onTranscodeFailed(Exception e) { | ||||
| 						Log.d(Config.LOGTAG,"video transcoding failed "+e.getMessage()); | ||||
| 						processAsFile(); | ||||
| 					} | ||||
| 				}; | ||||
| 				MediaTranscoder.getInstance().transcodeVideo(fileDescriptor, file.getAbsolutePath(), | ||||
| 						MediaFormatStrategyPresets.createAndroid720pStrategy(), listener); | ||||
| 			} | ||||
| 
 | ||||
| 			@Override | ||||
| 			public void run() { | ||||
| 				final String mimeType = MimeUtils.guessMimeTypeFromUri(XmppConnectionService.this, uri); | ||||
| 				if (mimeType != null && mimeType.startsWith("video/") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { | ||||
| 					try { | ||||
| 						processAsVideo(); | ||||
| 					} catch (Throwable e) { | ||||
| 						processAsFile(); | ||||
| 					} | ||||
| 				} else { | ||||
| 					processAsFile(); | ||||
| 				} | ||||
| 
 | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1543,9 +1543,26 @@ public class ConversationActivity extends XmppActivity | |||
| 		} | ||||
| 		final Toast prepareFileToast = Toast.makeText(getApplicationContext(),getText(R.string.preparing_file), Toast.LENGTH_LONG); | ||||
| 		prepareFileToast.show(); | ||||
| 		xmppConnectionService.attachFileToConversation(conversation, uri, new UiCallback<Message>() { | ||||
| 		xmppConnectionService.attachFileToConversation(conversation, uri, new UiInformableCallback<Message>() { | ||||
| 			@Override | ||||
| 			public void inform(final String text) { | ||||
| 				hidePrepareFileToast(prepareFileToast); | ||||
| 				runOnUiThread(new Runnable() { | ||||
| 					@Override | ||||
| 					public void run() { | ||||
| 						replaceToast(text); | ||||
| 					} | ||||
| 				}); | ||||
| 			} | ||||
| 
 | ||||
| 			@Override | ||||
| 			public void success(Message message) { | ||||
| 				runOnUiThread(new Runnable() { | ||||
| 					@Override | ||||
| 					public void run() { | ||||
| 						hideToast(); | ||||
| 					} | ||||
| 				}); | ||||
| 				hidePrepareFileToast(prepareFileToast); | ||||
| 				xmppConnectionService.sendMessage(message); | ||||
| 			} | ||||
|  |  | |||
|  | @ -59,7 +59,17 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer | |||
| 	private Toast mToast; | ||||
| 	private AtomicInteger attachmentCounter = new AtomicInteger(0); | ||||
| 
 | ||||
| 	private UiCallback<Message> attachFileCallback = new UiCallback<Message>() { | ||||
| 	private UiInformableCallback<Message> attachFileCallback = new UiInformableCallback<Message>() { | ||||
| 
 | ||||
| 		@Override | ||||
| 		public void inform(final String text) { | ||||
| 			runOnUiThread(new Runnable() { | ||||
| 				@Override | ||||
| 				public void run() { | ||||
| 					replaceToast(text); | ||||
| 				} | ||||
| 			}); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public void userInputRequried(PendingIntent pi, Message object) { | ||||
|  | @ -293,8 +303,7 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer | |||
| 					} else { | ||||
| 						replaceToast(getString(R.string.preparing_file)); | ||||
| 						ShareWithActivity.this.xmppConnectionService | ||||
| 								.attachFileToConversation(conversation, share.uris.get(0), | ||||
| 										attachFileCallback); | ||||
| 								.attachFileToConversation(conversation, share.uris.get(0), attachFileCallback); | ||||
| 					} | ||||
| 				} | ||||
| 			}; | ||||
|  |  | |||
|  | @ -0,0 +1,5 @@ | |||
| package eu.siacs.conversations.ui; | ||||
| 
 | ||||
| public interface UiInformableCallback<T> extends UiCallback<T> { | ||||
|     void inform(String text); | ||||
| } | ||||
|  | @ -732,4 +732,5 @@ | |||
| 	<string name="pref_automatically_delete_messages_description">Automatically delete messages from this device that are older than the configured time frame.</string> | ||||
| 	<string name="encrypting_message">Encrypting message</string> | ||||
| 	<string name="not_fetching_history_retention_period">Overstepping local retention period.</string> | ||||
| 	<string name="transcoding_video_progress">Compressing video (%s%% completed)</string> | ||||
| </resources> | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <paths> | ||||
|     <external-path name="external" path="/"/> | ||||
|     <files-path path="Pictures/" name="pics" /> | ||||
|     <files-path path="Images/" name="pictures" /> | ||||
|     <files-path path="Videos" name="videos"/> | ||||
|     <files-path path="Files/" name="files" /> | ||||
|     <cache-path path="Camera/" name="cam" /> | ||||
|     <cache-path path="Camera/" name="camera" /> | ||||
| </paths> | ||||
		Loading…
	
		Reference in New Issue
	
	 Daniel Gultsch
						Daniel Gultsch