prepare video before recoding starts

This commit is contained in:
B. Petersen 2019-05-11 00:00:49 +02:00
parent a959b173fa
commit 582f2d0626
No known key found for this signature in database
GPG key ID: 3B88E92DEA8E9AFC
3 changed files with 78 additions and 25 deletions

View file

@ -1018,19 +1018,22 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
DcMsg msg = (DcMsg)param[0]; DcMsg msg = (DcMsg)param[0];
Integer recompress = (Integer)param[1]; Integer recompress = (Integer)param[1];
if (action==ACTION_SEND_OUT) { if (action==ACTION_SEND_OUT) {
dcContext.setDraft(dcChat.getId(), null);
if(msg!=null) { if(msg!=null) {
if(recompress!=0) { if(recompress!=0) {
if(recompress==DcMsg.DC_MSG_IMAGE) { if(recompress==DcMsg.DC_MSG_IMAGE) {
BitmapUtil.recodeImageMsg(ConversationActivity.this, msg); BitmapUtil.recodeImageMsg(ConversationActivity.this, msg);
} }
else if(recompress==DcMsg.DC_MSG_VIDEO) { else if(recompress==DcMsg.DC_MSG_VIDEO) {
VideoRecoder.recodeVideo(ConversationActivity.this, msg); VideoRecoder.prepareVideo(ConversationActivity.this, dcChat.getId(), msg);
} }
} }
dcContext.sendMsg(dcChat.getId(), msg); dcContext.sendMsg(dcChat.getId(), msg);
Util.runOnMain(()-> sendComplete(dcChat.getId())); Util.runOnMain(()-> sendComplete(dcChat.getId()));
} }
dcContext.setDraft(dcChat.getId(), null);
} }
else { else {
dcContext.setDraft(dcChat.getId(), msg); dcContext.setDraft(dcChat.getId(), msg);

View file

@ -43,6 +43,9 @@ import org.thoughtcrime.securesms.components.ComposeText;
import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.Address;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -180,6 +183,39 @@ public class Util {
return total; return total;
} }
public static boolean moveFile(String fromPath, String toPath) {
boolean success = false;
// 1st try: a simple rename
try {
File fromFile = new File(fromPath);
File toFile = new File(toPath);
toFile.delete();
if(fromFile.renameTo(toFile)) {
success = true;
}
}
catch (Exception e) {
e.printStackTrace();
}
// 2nd try: copy file
if (!success) {
try {
InputStream fromStream = new FileInputStream(fromPath);
OutputStream toStream = new FileOutputStream(toPath);
if(Util.copy(fromStream, toStream)>0) {
success = true;
}
}
catch (Exception e) {
e.printStackTrace();
}
}
return success;
}
public static List<String> split(String source, String delimiter) { public static List<String> split(String source, String delimiter) {
List<String> results = new LinkedList<>(); List<String> results = new LinkedList<>();

View file

@ -23,6 +23,7 @@ import com.googlecode.mp4parser.util.Matrix;
import com.googlecode.mp4parser.util.Path; import com.googlecode.mp4parser.util.Path;
import org.thoughtcrime.securesms.connect.DcHelper; import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.util.Util;
import java.io.File; import java.io.File;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -757,17 +758,22 @@ public class VideoRecoder {
return size; return size;
} }
public static boolean recodeVideo(Context context, DcMsg msg) { // prepareVideo() assumes the msg object is set up properly to being sent;
// the function fills out missing information and also recodes the video as needed;
if (!canRecode()) { // to get a responsive ui, DcChat.prepareMsg() may be called.
return false; public static void prepareVideo(Context context, int chatId, DcMsg msg) {
}
String inPath = msg.getFile(); String inPath = msg.getFile();
if (!canRecode()) {
Log.w(TAG, String.format("recoding for %s failed: this system cannot recode videos", inPath));
return;
}
VideoEditedInfo vei = getVideoEditInfoFromFile(inPath); VideoEditedInfo vei = getVideoEditInfoFromFile(inPath);
if(vei==null) { if(vei==null) {
return false; Log.w(TAG, String.format("recoding for %s failed: cannot get info", inPath));
return;
} }
vei.rotationValue = vei.originalRotationValue; vei.rotationValue = vei.originalRotationValue;
@ -795,7 +801,7 @@ public class VideoRecoder {
} }
} }
// get video dimensions // calculate video dimensions
int maxSide = vei.resultBitrate>400000? 640 : 480; int maxSide = vei.resultBitrate>400000? 640 : 480;
vei.resultWidth = vei.originalWidth; vei.resultWidth = vei.originalWidth;
vei.resultHeight = vei.originalHeight; vei.resultHeight = vei.originalHeight;
@ -805,21 +811,7 @@ public class VideoRecoder {
vei.resultHeight *= scale; vei.resultHeight *= scale;
} }
// calulate bytes // we know the most important things now, prepare the message to get a resposive ui
vei.estimatedBytes = VideoRecoder.calculateEstimatedSize((float) resultDurationMs / vei.originalDurationMs,
vei.resultBitrate, vei.originalDurationMs, vei.originalAudioBytes);
if(vei.estimatedBytes>MAX_BYTES) {
return false;
}
String outPath = DcHelper.getContext(context).getBlobdirFile(inPath);
VideoRecoder videoRecoder = new VideoRecoder();
if (!videoRecoder.convertVideo(vei, outPath)) {
return false;
}
msg.setFile(outPath, null);
if(vei.originalRotationValue==90||vei.originalRotationValue==270) { if(vei.originalRotationValue==90||vei.originalRotationValue==270) {
msg.setDimension(vei.resultHeight, vei.resultWidth); msg.setDimension(vei.resultHeight, vei.resultWidth);
} }
@ -827,8 +819,30 @@ public class VideoRecoder {
msg.setDimension(vei.resultWidth, vei.resultHeight); msg.setDimension(vei.resultWidth, vei.resultHeight);
} }
msg.setDuration((int)resultDurationMs); msg.setDuration((int)resultDurationMs);
DcHelper.getContext(context).prepareMsg(chatId, msg);
// calulate bytes
vei.estimatedBytes = VideoRecoder.calculateEstimatedSize((float) resultDurationMs / vei.originalDurationMs,
vei.resultBitrate, vei.originalDurationMs, vei.originalAudioBytes);
if(vei.estimatedBytes>MAX_BYTES) {
Log.w(TAG, String.format("recoding for %s: resulting file may too large", inPath));
// continue anyway
}
// recode
String tempPath = DcHelper.getContext(context).getBlobdirFile(inPath);
VideoRecoder videoRecoder = new VideoRecoder();
if (!videoRecoder.convertVideo(vei, tempPath)) {
Log.w(TAG, String.format("recoding for %s failed: cannot convert to temporary file %s", inPath, tempPath));
return;
}
if(!Util.moveFile(tempPath, inPath)) {
Log.w(TAG, String.format("recoding for %s failed: cannot move temporary file %s", inPath, tempPath));
return;
}
Log.i(TAG, String.format("recoding for %s done", inPath)); Log.i(TAG, String.format("recoding for %s done", inPath));
return true;
} }
} }