Video convert queue, bug fixes
|
@ -80,7 +80,7 @@ android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 8
|
minSdkVersion 8
|
||||||
targetSdkVersion 19
|
targetSdkVersion 19
|
||||||
versionCode 330
|
versionCode 331
|
||||||
versionName "1.9.0"
|
versionName "1.9.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class ContactsController {
|
||||||
try {
|
try {
|
||||||
nameDisplayOrder = Settings.System.getInt(ApplicationLoader.applicationContext.getContentResolver(), "android.contacts.DISPLAY_ORDER");
|
nameDisplayOrder = Settings.System.getInt(ApplicationLoader.applicationContext.getContentResolver(), "android.contacts.DISPLAY_ORDER");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
//don't promt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -586,41 +586,69 @@ public class ImageLoader {
|
||||||
private HashMap<Integer, File> createMediaPaths() {
|
private HashMap<Integer, File> createMediaPaths() {
|
||||||
HashMap<Integer, File> mediaDirs = new HashMap<Integer, File>();
|
HashMap<Integer, File> mediaDirs = new HashMap<Integer, File>();
|
||||||
File cachePath = AndroidUtilities.getCacheDir();
|
File cachePath = AndroidUtilities.getCacheDir();
|
||||||
try {
|
if (!cachePath.isDirectory()) {
|
||||||
cachePath.mkdirs();
|
try {
|
||||||
new File(cachePath, ".nomedia").createNewFile();
|
cachePath.mkdirs();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
|
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
||||||
File telegramPath = new File(Environment.getExternalStorageDirectory(), LocaleController.getString("AppName", R.string.AppName));
|
File telegramPath = new File(Environment.getExternalStorageDirectory(), LocaleController.getString("AppName", R.string.AppName));
|
||||||
telegramPath.mkdirs();
|
telegramPath.mkdirs();
|
||||||
|
if (telegramPath.isDirectory()) {
|
||||||
|
try {
|
||||||
|
File imagePath = new File(telegramPath, "Images");
|
||||||
|
imagePath.mkdir();
|
||||||
|
if (imagePath.isDirectory()) {
|
||||||
|
new File(imagePath, ".nomedia").createNewFile();
|
||||||
|
mediaDirs.put(FileLoader.MEDIA_DIR_IMAGE, imagePath);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
|
||||||
File imagePath = new File(telegramPath, "Images");
|
try {
|
||||||
imagePath.mkdir();
|
File videoPath = new File(telegramPath, "Video");
|
||||||
new File(imagePath, ".nomedia").createNewFile();
|
videoPath.mkdir();
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_IMAGE, imagePath);
|
if (videoPath.isDirectory()) {
|
||||||
|
new File(videoPath, ".nomedia").createNewFile();
|
||||||
|
mediaDirs.put(FileLoader.MEDIA_DIR_VIDEO, videoPath);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
|
||||||
File videoPath = new File(telegramPath, "Video");
|
try {
|
||||||
videoPath.mkdir();
|
File audioPath = new File(telegramPath, "Audio");
|
||||||
new File(videoPath, ".nomedia").createNewFile();
|
audioPath.mkdir();
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_VIDEO, videoPath);
|
if (audioPath.isDirectory()) {
|
||||||
|
new File(audioPath, ".nomedia").createNewFile();
|
||||||
|
mediaDirs.put(FileLoader.MEDIA_DIR_AUDIO, audioPath);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
|
||||||
File audioPath = new File(telegramPath, "Audio");
|
try {
|
||||||
audioPath.mkdir();
|
File documentPath = new File(telegramPath, "Documents");
|
||||||
new File(audioPath, ".nomedia").createNewFile();
|
documentPath.mkdir();
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_AUDIO, audioPath);
|
if (documentPath.isDirectory()) {
|
||||||
|
new File(documentPath, ".nomedia").createNewFile();
|
||||||
File documentPath = new File(telegramPath, "Documents");
|
mediaDirs.put(FileLoader.MEDIA_DIR_DOCUMENT, documentPath);
|
||||||
documentPath.mkdir();
|
}
|
||||||
new File(documentPath, ".nomedia").createNewFile();
|
} catch (Exception e) {
|
||||||
mediaDirs.put(FileLoader.MEDIA_DIR_DOCUMENT, documentPath);
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mediaDirs;
|
return mediaDirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
package org.telegram.android;
|
package org.telegram.android;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
|
@ -21,16 +22,26 @@ import android.media.AudioFormat;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.AudioRecord;
|
import android.media.AudioRecord;
|
||||||
import android.media.AudioTrack;
|
import android.media.AudioTrack;
|
||||||
|
import android.media.MediaCodec;
|
||||||
|
import android.media.MediaCodecInfo;
|
||||||
|
import android.media.MediaCodecList;
|
||||||
|
import android.media.MediaExtractor;
|
||||||
|
import android.media.MediaFormat;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.media.MediaRecorder;
|
import android.media.MediaRecorder;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import org.telegram.android.video.InputSurface;
|
||||||
|
import org.telegram.android.video.MP4Builder;
|
||||||
|
import org.telegram.android.video.Mp4Movie;
|
||||||
|
import org.telegram.android.video.OutputSurface;
|
||||||
import org.telegram.messenger.ConnectionsManager;
|
import org.telegram.messenger.ConnectionsManager;
|
||||||
import org.telegram.messenger.DispatchQueue;
|
import org.telegram.messenger.DispatchQueue;
|
||||||
import org.telegram.messenger.FileLoader;
|
import org.telegram.messenger.FileLoader;
|
||||||
|
@ -133,6 +144,17 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static String MIME_TYPE = "video/avc";
|
||||||
|
private final static int PROCESSOR_TYPE_OTHER = 0;
|
||||||
|
private final static int PROCESSOR_TYPE_QCOM = 1;
|
||||||
|
private final static int PROCESSOR_TYPE_INTEL = 2;
|
||||||
|
private final Object videoConvertSync = new Object();
|
||||||
|
|
||||||
|
private ArrayList<MessageObject> videoConvertQueue = new ArrayList<MessageObject>();
|
||||||
|
private final Object videoQueueSync = new Object();
|
||||||
|
private boolean cancelCurrentVideoConversion = false;
|
||||||
|
private boolean videoConvertFirstWrite = true;
|
||||||
|
|
||||||
public static final int AUTODOWNLOAD_MASK_PHOTO = 1;
|
public static final int AUTODOWNLOAD_MASK_PHOTO = 1;
|
||||||
public static final int AUTODOWNLOAD_MASK_AUDIO = 2;
|
public static final int AUTODOWNLOAD_MASK_AUDIO = 2;
|
||||||
public static final int AUTODOWNLOAD_MASK_VIDEO = 4;
|
public static final int AUTODOWNLOAD_MASK_VIDEO = 4;
|
||||||
|
@ -1441,11 +1463,10 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
||||||
public void run() {
|
public void run() {
|
||||||
audioToSend.date = ConnectionsManager.getInstance().getCurrentTime();
|
audioToSend.date = ConnectionsManager.getInstance().getCurrentTime();
|
||||||
audioToSend.size = (int) recordingAudioFileToSend.length();
|
audioToSend.size = (int) recordingAudioFileToSend.length();
|
||||||
audioToSend.path = recordingAudioFileToSend.getAbsolutePath();
|
|
||||||
long duration = recordTimeCount;
|
long duration = recordTimeCount;
|
||||||
audioToSend.duration = (int) (duration / 1000);
|
audioToSend.duration = (int) (duration / 1000);
|
||||||
if (duration > 700) {
|
if (duration > 700) {
|
||||||
SendMessagesHelper.getInstance().sendMessage(audioToSend, recordDialogId);
|
SendMessagesHelper.getInstance().sendMessage(audioToSend, recordingAudioFileToSend.getAbsolutePath(), recordDialogId);
|
||||||
} else {
|
} else {
|
||||||
recordingAudioFileToSend.delete();
|
recordingAudioFileToSend.delete();
|
||||||
}
|
}
|
||||||
|
@ -1838,4 +1859,600 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void scheduleVideoConvert(MessageObject messageObject) {
|
||||||
|
videoConvertQueue.add(messageObject);
|
||||||
|
if (videoConvertQueue.size() == 1) {
|
||||||
|
startVideoConvertFromQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelVideoConvert(MessageObject messageObject) {
|
||||||
|
if (!videoConvertQueue.isEmpty()) {
|
||||||
|
if (videoConvertQueue.get(0) == messageObject) {
|
||||||
|
synchronized (videoConvertSync) {
|
||||||
|
cancelCurrentVideoConversion = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
videoConvertQueue.remove(messageObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startVideoConvertFromQueue() {
|
||||||
|
if (!videoConvertQueue.isEmpty()) {
|
||||||
|
MessageObject messageObject = videoConvertQueue.get(0);
|
||||||
|
VideoConvertRunnable.runConversion(messageObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MediaCodecInfo selectCodec(String mimeType) {
|
||||||
|
int numCodecs = MediaCodecList.getCodecCount();
|
||||||
|
MediaCodecInfo lastCodecInfo = null;
|
||||||
|
for (int i = 0; i < numCodecs; i++) {
|
||||||
|
MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
|
||||||
|
if (!codecInfo.isEncoder()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] types = codecInfo.getSupportedTypes();
|
||||||
|
for (String type : types) {
|
||||||
|
if (type.equalsIgnoreCase(mimeType)) {
|
||||||
|
lastCodecInfo = codecInfo;
|
||||||
|
FileLog.e("tmessages", "available codec = " + codecInfo.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastCodecInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isRecognizedFormat(int colorFormat) {
|
||||||
|
switch (colorFormat) {
|
||||||
|
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
|
||||||
|
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
|
||||||
|
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
|
||||||
|
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
|
||||||
|
case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int selectColorFormat(MediaCodecInfo codecInfo, String mimeType) {
|
||||||
|
MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
|
||||||
|
for (int i = 0; i < capabilities.colorFormats.length; i++) {
|
||||||
|
int colorFormat = capabilities.colorFormats[i];
|
||||||
|
if (isRecognizedFormat(colorFormat)) {
|
||||||
|
return colorFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(16)
|
||||||
|
private int selectTrack(MediaExtractor extractor, boolean audio) {
|
||||||
|
int numTracks = extractor.getTrackCount();
|
||||||
|
for (int i = 0; i < numTracks; i++) {
|
||||||
|
MediaFormat format = extractor.getTrackFormat(i);
|
||||||
|
String mime = format.getString(MediaFormat.KEY_MIME);
|
||||||
|
if (audio) {
|
||||||
|
if (mime.startsWith("audio/")) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mime.startsWith("video/")) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void didWriteData(final MessageObject messageObject, final File file, final long finalSize, final boolean error) {
|
||||||
|
final boolean firstWrite = videoConvertFirstWrite;
|
||||||
|
if (firstWrite) {
|
||||||
|
videoConvertFirstWrite = false;
|
||||||
|
}
|
||||||
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (error) {
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.FilePreparingFailed, messageObject, file.toString());
|
||||||
|
} else {
|
||||||
|
if (firstWrite) {
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.FilePreparingStarted, messageObject, file.toString());
|
||||||
|
}
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileNewChunkAvailable, messageObject, file.toString(), finalSize);
|
||||||
|
}
|
||||||
|
if (finalSize != 0) {
|
||||||
|
synchronized (videoConvertSync) {
|
||||||
|
cancelCurrentVideoConversion = false;
|
||||||
|
}
|
||||||
|
videoConvertQueue.remove(messageObject);
|
||||||
|
startVideoConvertFromQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(16)
|
||||||
|
private long readAndWriteTrack(final MessageObject messageObject, MediaExtractor extractor, MP4Builder mediaMuxer, MediaCodec.BufferInfo info, long start, long end, File file, boolean isAudio) throws Exception {
|
||||||
|
int trackIndex = selectTrack(extractor, isAudio);
|
||||||
|
if (trackIndex >= 0) {
|
||||||
|
extractor.selectTrack(trackIndex);
|
||||||
|
MediaFormat trackFormat = extractor.getTrackFormat(trackIndex);
|
||||||
|
int muxerTrackIndex = mediaMuxer.addTrack(trackFormat, isAudio);
|
||||||
|
int maxBufferSize = trackFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
|
||||||
|
boolean inputDone = false;
|
||||||
|
if (start > 0) {
|
||||||
|
extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
|
||||||
|
} else {
|
||||||
|
extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
|
||||||
|
}
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize);
|
||||||
|
long startTime = -1;
|
||||||
|
|
||||||
|
checkConversionCanceled();
|
||||||
|
|
||||||
|
while (!inputDone) {
|
||||||
|
checkConversionCanceled();
|
||||||
|
|
||||||
|
boolean eof = false;
|
||||||
|
int index = extractor.getSampleTrackIndex();
|
||||||
|
if (index == trackIndex) {
|
||||||
|
info.size = extractor.readSampleData(buffer, 0);
|
||||||
|
|
||||||
|
if (info.size < 0) {
|
||||||
|
info.size = 0;
|
||||||
|
eof = true;
|
||||||
|
} else {
|
||||||
|
info.presentationTimeUs = extractor.getSampleTime();
|
||||||
|
if (start > 0 && startTime == -1) {
|
||||||
|
startTime = info.presentationTimeUs;
|
||||||
|
}
|
||||||
|
if (end < 0 || info.presentationTimeUs < end) {
|
||||||
|
info.offset = 0;
|
||||||
|
info.flags = extractor.getSampleFlags();
|
||||||
|
if (!isAudio) {
|
||||||
|
buffer.limit(info.offset + info.size);
|
||||||
|
buffer.position(info.offset);
|
||||||
|
buffer.putInt(info.size - 4);
|
||||||
|
}
|
||||||
|
if (mediaMuxer.writeSampleData(muxerTrackIndex, buffer, info)) {
|
||||||
|
didWriteData(messageObject, file, 0, false);
|
||||||
|
}
|
||||||
|
extractor.advance();
|
||||||
|
} else {
|
||||||
|
eof = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (index == -1) {
|
||||||
|
eof = true;
|
||||||
|
}
|
||||||
|
if (eof) {
|
||||||
|
inputDone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extractor.unselectTrack(trackIndex);
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class VideoConvertRunnable implements Runnable {
|
||||||
|
|
||||||
|
private MessageObject messageObject;
|
||||||
|
|
||||||
|
private VideoConvertRunnable(MessageObject message) {
|
||||||
|
messageObject = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
MediaController.getInstance().convertVideo(messageObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runConversion(final MessageObject obj) {
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
VideoConvertRunnable wrapper = new VideoConvertRunnable(obj);
|
||||||
|
Thread th = new Thread(wrapper, "VideoConvertRunnable");
|
||||||
|
th.start();
|
||||||
|
th.join();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkConversionCanceled() throws Exception {
|
||||||
|
boolean cancelConversion = false;
|
||||||
|
synchronized (videoConvertSync) {
|
||||||
|
cancelConversion = cancelCurrentVideoConversion;
|
||||||
|
}
|
||||||
|
if (cancelConversion) {
|
||||||
|
throw new RuntimeException("canceled conversion");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(16)
|
||||||
|
private boolean convertVideo(final MessageObject messageObject) {
|
||||||
|
String videoPath = messageObject.messageOwner.videoEditedInfo.originalPath;
|
||||||
|
long startTime = messageObject.messageOwner.videoEditedInfo.startTime;
|
||||||
|
long endTime = messageObject.messageOwner.videoEditedInfo.endTime;
|
||||||
|
int resultWidth = messageObject.messageOwner.videoEditedInfo.resultWidth;
|
||||||
|
int resultHeight = messageObject.messageOwner.videoEditedInfo.resultHeight;
|
||||||
|
int rotationValue = messageObject.messageOwner.videoEditedInfo.rotationValue;
|
||||||
|
int originalWidth = messageObject.messageOwner.videoEditedInfo.originalWidth;
|
||||||
|
int originalHeight = messageObject.messageOwner.videoEditedInfo.originalHeight;
|
||||||
|
int bitrate = messageObject.messageOwner.videoEditedInfo.bitrate;
|
||||||
|
File cacheFile = new File(messageObject.messageOwner.attachPath);
|
||||||
|
|
||||||
|
File inputFile = new File(videoPath);
|
||||||
|
if (!inputFile.canRead()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
videoConvertFirstWrite = true;
|
||||||
|
boolean error = false;
|
||||||
|
long videoStartTime = startTime;
|
||||||
|
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (resultWidth != 0 && resultHeight != 0) {
|
||||||
|
MP4Builder mediaMuxer = null;
|
||||||
|
MediaExtractor extractor = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
|
||||||
|
Mp4Movie movie = new Mp4Movie();
|
||||||
|
movie.setCacheFile(cacheFile);
|
||||||
|
movie.setRotation(rotationValue);
|
||||||
|
resultHeight = 352;
|
||||||
|
movie.setSize(resultWidth, resultHeight);
|
||||||
|
mediaMuxer = new MP4Builder().createMovie(movie);
|
||||||
|
extractor = new MediaExtractor();
|
||||||
|
extractor.setDataSource(inputFile.toString());
|
||||||
|
|
||||||
|
checkConversionCanceled();
|
||||||
|
|
||||||
|
if (resultWidth != originalWidth || resultHeight != originalHeight) {
|
||||||
|
int videoIndex = -5;
|
||||||
|
videoIndex = selectTrack(extractor, false);
|
||||||
|
if (videoIndex >= 0) {
|
||||||
|
MediaCodec decoder = null;
|
||||||
|
MediaCodec encoder = null;
|
||||||
|
InputSurface inputSurface = null;
|
||||||
|
OutputSurface outputSurface = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
long videoTime = -1;
|
||||||
|
boolean outputDone = false;
|
||||||
|
boolean inputDone = false;
|
||||||
|
boolean decoderDone = false;
|
||||||
|
int swapUV = 0;
|
||||||
|
int videoTrackIndex = -5;
|
||||||
|
|
||||||
|
int colorFormat = 0;
|
||||||
|
int processorType = PROCESSOR_TYPE_OTHER;
|
||||||
|
if (Build.VERSION.SDK_INT < 18) {
|
||||||
|
MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
|
||||||
|
colorFormat = selectColorFormat(codecInfo, MIME_TYPE);
|
||||||
|
String manufacturer = Build.MANUFACTURER.toLowerCase();
|
||||||
|
if (codecInfo.getName().contains("OMX.qcom.")) {
|
||||||
|
processorType = PROCESSOR_TYPE_QCOM;
|
||||||
|
if (Build.VERSION.SDK_INT == 16) {
|
||||||
|
if (manufacturer.equals("lge") || manufacturer.equals("nokia")) {
|
||||||
|
swapUV = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (codecInfo.getName().contains("OMX.Intel.")) {
|
||||||
|
processorType = PROCESSOR_TYPE_INTEL;
|
||||||
|
}
|
||||||
|
FileLog.e("tmessages", "codec = " + codecInfo.getName() + " manufacturer = " + manufacturer);
|
||||||
|
} else {
|
||||||
|
colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
|
||||||
|
}
|
||||||
|
FileLog.e("tmessages", "colorFormat = " + colorFormat);
|
||||||
|
|
||||||
|
int resultHeightAligned = resultHeight;
|
||||||
|
int padding = 0;
|
||||||
|
int bufferSize = resultWidth * resultHeight * 3 / 2;
|
||||||
|
if (processorType == PROCESSOR_TYPE_OTHER) {
|
||||||
|
if (resultHeight % 16 != 0) {
|
||||||
|
resultHeightAligned += (16 - (resultHeight % 16));
|
||||||
|
padding = resultWidth * (resultHeightAligned - resultHeight);
|
||||||
|
bufferSize += padding * 5 / 4;
|
||||||
|
}
|
||||||
|
} else if (processorType == PROCESSOR_TYPE_QCOM) {
|
||||||
|
if (!Build.MANUFACTURER.toLowerCase().equals("lge")) {
|
||||||
|
int uvoffset = (resultWidth * resultHeight + 2047) & ~2047;
|
||||||
|
padding = uvoffset - (resultWidth * resultHeight);
|
||||||
|
bufferSize += padding;
|
||||||
|
}
|
||||||
|
} else if (processorType == PROCESSOR_TYPE_INTEL) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extractor.selectTrack(videoIndex);
|
||||||
|
if (startTime > 0) {
|
||||||
|
extractor.seekTo(startTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
|
||||||
|
} else {
|
||||||
|
extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
|
||||||
|
}
|
||||||
|
MediaFormat inputFormat = extractor.getTrackFormat(videoIndex);
|
||||||
|
|
||||||
|
MediaFormat outputFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight);
|
||||||
|
outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
|
||||||
|
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate != 0 ? bitrate : 921600);
|
||||||
|
outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 25);
|
||||||
|
outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
|
||||||
|
if (Build.VERSION.SDK_INT < 18) {
|
||||||
|
outputFormat.setInteger("stride", resultWidth);
|
||||||
|
outputFormat.setInteger("slice-height", resultHeightAligned);
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder = MediaCodec.createEncoderByType(MIME_TYPE);
|
||||||
|
encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
|
||||||
|
if (Build.VERSION.SDK_INT >= 18) {
|
||||||
|
inputSurface = new InputSurface(encoder.createInputSurface());
|
||||||
|
inputSurface.makeCurrent();
|
||||||
|
}
|
||||||
|
encoder.start();
|
||||||
|
|
||||||
|
decoder = MediaCodec.createDecoderByType(inputFormat.getString(MediaFormat.KEY_MIME));
|
||||||
|
if (Build.VERSION.SDK_INT >= 18) {
|
||||||
|
outputSurface = new OutputSurface();
|
||||||
|
} else {
|
||||||
|
outputSurface = new OutputSurface(resultWidth, resultHeight);
|
||||||
|
}
|
||||||
|
decoder.configure(inputFormat, outputSurface.getSurface(), null, 0);
|
||||||
|
decoder.start();
|
||||||
|
|
||||||
|
final int TIMEOUT_USEC = 2500;
|
||||||
|
ByteBuffer[] decoderInputBuffers = decoder.getInputBuffers();
|
||||||
|
ByteBuffer[] encoderOutputBuffers = encoder.getOutputBuffers();
|
||||||
|
ByteBuffer[] encoderInputBuffers = null;
|
||||||
|
if (Build.VERSION.SDK_INT < 18) {
|
||||||
|
encoderInputBuffers = encoder.getInputBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkConversionCanceled();
|
||||||
|
|
||||||
|
while (!outputDone) {
|
||||||
|
checkConversionCanceled();
|
||||||
|
if (!inputDone) {
|
||||||
|
boolean eof = false;
|
||||||
|
int index = extractor.getSampleTrackIndex();
|
||||||
|
if (index == videoIndex) {
|
||||||
|
int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
|
||||||
|
if (inputBufIndex >= 0) {
|
||||||
|
ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
|
||||||
|
int chunkSize = extractor.readSampleData(inputBuf, 0);
|
||||||
|
if (chunkSize < 0) {
|
||||||
|
decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
||||||
|
inputDone = true;
|
||||||
|
} else {
|
||||||
|
decoder.queueInputBuffer(inputBufIndex, 0, chunkSize, extractor.getSampleTime(), 0);
|
||||||
|
extractor.advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (index == -1) {
|
||||||
|
eof = true;
|
||||||
|
}
|
||||||
|
if (eof) {
|
||||||
|
int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
|
||||||
|
if (inputBufIndex >= 0) {
|
||||||
|
decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
||||||
|
inputDone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean decoderOutputAvailable = !decoderDone;
|
||||||
|
boolean encoderOutputAvailable = true;
|
||||||
|
while (decoderOutputAvailable || encoderOutputAvailable) {
|
||||||
|
checkConversionCanceled();
|
||||||
|
int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
|
||||||
|
if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
|
||||||
|
encoderOutputAvailable = false;
|
||||||
|
} else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
|
||||||
|
encoderOutputBuffers = encoder.getOutputBuffers();
|
||||||
|
} else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
|
||||||
|
MediaFormat newFormat = encoder.getOutputFormat();
|
||||||
|
if (videoTrackIndex == -5) {
|
||||||
|
videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
|
||||||
|
}
|
||||||
|
} else if (encoderStatus < 0) {
|
||||||
|
throw new RuntimeException("unexpected result from encoder.dequeueOutputBuffer: " + encoderStatus);
|
||||||
|
} else {
|
||||||
|
ByteBuffer encodedData = encoderOutputBuffers[encoderStatus];
|
||||||
|
if (encodedData == null) {
|
||||||
|
throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null");
|
||||||
|
}
|
||||||
|
if (info.size > 1) {
|
||||||
|
if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
|
||||||
|
encodedData.limit(info.offset + info.size);
|
||||||
|
encodedData.position(info.offset);
|
||||||
|
encodedData.putInt(Integer.reverseBytes(info.size - 4));
|
||||||
|
if (mediaMuxer.writeSampleData(videoTrackIndex, encodedData, info)) {
|
||||||
|
didWriteData(messageObject, cacheFile, 0, false);
|
||||||
|
}
|
||||||
|
} else if (videoTrackIndex == -5) {
|
||||||
|
byte[] csd = new byte[info.size];
|
||||||
|
encodedData.limit(info.offset + info.size);
|
||||||
|
encodedData.position(info.offset);
|
||||||
|
encodedData.get(csd);
|
||||||
|
ByteBuffer sps = null;
|
||||||
|
ByteBuffer pps = null;
|
||||||
|
for (int a = info.size - 1; a >= 0; a--) {
|
||||||
|
if (a > 3) {
|
||||||
|
if (csd[a] == 1 && csd[a - 1] == 0 && csd[a - 2] == 0 && csd[a - 3] == 0) {
|
||||||
|
sps = ByteBuffer.allocate(a - 3);
|
||||||
|
pps = ByteBuffer.allocate(info.size - (a - 3));
|
||||||
|
sps.put(csd, 0, a - 3).position(0);
|
||||||
|
pps.put(csd, a - 3, info.size - (a - 3)).position(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaFormat newFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight);
|
||||||
|
if (sps != null && pps != null) {
|
||||||
|
newFormat.setByteBuffer("csd-0", sps);
|
||||||
|
newFormat.setByteBuffer("csd-1", pps);
|
||||||
|
}
|
||||||
|
videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outputDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
|
||||||
|
encoder.releaseOutputBuffer(encoderStatus, false);
|
||||||
|
}
|
||||||
|
if (encoderStatus != MediaCodec.INFO_TRY_AGAIN_LATER) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decoderDone) {
|
||||||
|
int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
|
||||||
|
if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
|
||||||
|
decoderOutputAvailable = false;
|
||||||
|
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
|
||||||
|
|
||||||
|
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
|
||||||
|
MediaFormat newFormat = decoder.getOutputFormat();
|
||||||
|
} else if (decoderStatus < 0) {
|
||||||
|
throw new RuntimeException("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
|
||||||
|
} else {
|
||||||
|
boolean doRender = false;
|
||||||
|
if (Build.VERSION.SDK_INT >= 18) {
|
||||||
|
doRender = info.size != 0;
|
||||||
|
} else {
|
||||||
|
doRender = info.size != 0 || info.presentationTimeUs != 0;
|
||||||
|
}
|
||||||
|
if (endTime > 0 && info.presentationTimeUs >= endTime) {
|
||||||
|
inputDone = true;
|
||||||
|
decoderDone = true;
|
||||||
|
doRender = false;
|
||||||
|
info.flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
|
||||||
|
}
|
||||||
|
if (startTime > 0 && videoTime == -1) {
|
||||||
|
if (info.presentationTimeUs < startTime) {
|
||||||
|
doRender = false;
|
||||||
|
FileLog.e("tmessages", "drop frame startTime = " + startTime + " present time = " + info.presentationTimeUs);
|
||||||
|
} else {
|
||||||
|
videoTime = info.presentationTimeUs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decoder.releaseOutputBuffer(decoderStatus, doRender);
|
||||||
|
if (doRender) {
|
||||||
|
boolean errorWait = false;
|
||||||
|
try {
|
||||||
|
outputSurface.awaitNewImage();
|
||||||
|
} catch (Exception e) {
|
||||||
|
errorWait = true;
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
if (!errorWait) {
|
||||||
|
if (Build.VERSION.SDK_INT >= 18) {
|
||||||
|
outputSurface.drawImage(false);
|
||||||
|
inputSurface.setPresentationTime(info.presentationTimeUs * 1000);
|
||||||
|
inputSurface.swapBuffers();
|
||||||
|
} else {
|
||||||
|
int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
|
||||||
|
if (inputBufIndex >= 0) {
|
||||||
|
outputSurface.drawImage(true);
|
||||||
|
ByteBuffer rgbBuf = outputSurface.getFrame();
|
||||||
|
ByteBuffer yuvBuf = encoderInputBuffers[inputBufIndex];
|
||||||
|
yuvBuf.clear();
|
||||||
|
Utilities.convertVideoFrame(rgbBuf, yuvBuf, colorFormat, resultWidth, resultHeight, padding, swapUV);
|
||||||
|
encoder.queueInputBuffer(inputBufIndex, 0, bufferSize, info.presentationTimeUs, 0);
|
||||||
|
} else {
|
||||||
|
FileLog.e("tmessages", "input buffer not available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
|
||||||
|
decoderOutputAvailable = false;
|
||||||
|
FileLog.e("tmessages", "decoder stream end");
|
||||||
|
if (Build.VERSION.SDK_INT >= 18) {
|
||||||
|
encoder.signalEndOfInputStream();
|
||||||
|
} else {
|
||||||
|
int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
|
||||||
|
if (inputBufIndex >= 0) {
|
||||||
|
encoder.queueInputBuffer(inputBufIndex, 0, 1, info.presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (videoTime != -1) {
|
||||||
|
videoStartTime = videoTime;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
extractor.unselectTrack(videoIndex);
|
||||||
|
|
||||||
|
if (outputSurface != null) {
|
||||||
|
outputSurface.release();
|
||||||
|
outputSurface = null;
|
||||||
|
}
|
||||||
|
if (inputSurface != null) {
|
||||||
|
inputSurface.release();
|
||||||
|
inputSurface = null;
|
||||||
|
}
|
||||||
|
if (decoder != null) {
|
||||||
|
decoder.stop();
|
||||||
|
decoder.release();
|
||||||
|
decoder = null;
|
||||||
|
}
|
||||||
|
if (encoder != null) {
|
||||||
|
encoder.stop();
|
||||||
|
encoder.release();
|
||||||
|
encoder = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkConversionCanceled();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
long videoTime = readAndWriteTrack(messageObject, extractor, mediaMuxer, info, startTime, endTime, cacheFile, false);
|
||||||
|
if (videoTime != -1) {
|
||||||
|
videoStartTime = videoTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readAndWriteTrack(messageObject, extractor, mediaMuxer, info, videoStartTime, endTime, cacheFile, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
error = true;
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
} finally {
|
||||||
|
if (extractor != null) {
|
||||||
|
extractor.release();
|
||||||
|
extractor = null;
|
||||||
|
}
|
||||||
|
if (mediaMuxer != null) {
|
||||||
|
try {
|
||||||
|
mediaMuxer.finishMovie(false);
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
mediaMuxer = null;
|
||||||
|
}
|
||||||
|
FileLog.e("tmessages", "time = " + (System.currentTimeMillis() - time));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
didWriteData(messageObject, cacheFile, cacheFile.length(), error);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,4 +623,16 @@ public class MessageObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSending() {
|
||||||
|
return messageOwner.send_state == MESSAGE_SEND_STATE_SENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSendError() {
|
||||||
|
return messageOwner.send_state == MESSAGE_SEND_STATE_SEND_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSent() {
|
||||||
|
return messageOwner.send_state == MESSAGE_SEND_STATE_SENT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2450,7 +2450,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
public void run() {
|
public void run() {
|
||||||
for (HashMap.Entry<Integer, Integer> entry : corrected.entrySet()) {
|
for (HashMap.Entry<Integer, Integer> entry : corrected.entrySet()) {
|
||||||
Integer oldId = entry.getKey();
|
Integer oldId = entry.getKey();
|
||||||
SendMessagesHelper.getInstance().setMessageSent(oldId);
|
SendMessagesHelper.getInstance().processSentMessage(oldId);
|
||||||
Integer newId = entry.getValue();
|
Integer newId = entry.getValue();
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newId, null);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newId, null);
|
||||||
}
|
}
|
||||||
|
@ -3464,9 +3464,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||||
} else {
|
} else {
|
||||||
MessageObject currentDialogMessage = dialogMessage.get(dialog.top_message);
|
MessageObject currentDialogMessage = dialogMessage.get(dialog.top_message);
|
||||||
if (currentDialogMessage != null) {
|
if (currentDialogMessage != null) {
|
||||||
if (currentDialogMessage.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING && lastMessage.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
if (currentDialogMessage.isSending() && lastMessage.isSending()) {
|
||||||
change = true;
|
change = true;
|
||||||
} else if (dialog.last_message_date < lastMessage.messageOwner.date || dialog.last_message_date == lastMessage.messageOwner.date && lastMessage.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
} else if (dialog.last_message_date < lastMessage.messageOwner.date || dialog.last_message_date == lastMessage.messageOwner.date && lastMessage.isSending()) {
|
||||||
change = true;
|
change = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -39,6 +39,7 @@ public class NotificationCenter {
|
||||||
public static final int pushMessagesUpdated = 27;
|
public static final int pushMessagesUpdated = 27;
|
||||||
public static final int blockedUsersDidLoaded = 28;
|
public static final int blockedUsersDidLoaded = 28;
|
||||||
public static final int openedChatChanged = 29;
|
public static final int openedChatChanged = 29;
|
||||||
|
public static final int hideEmojiKeyboard = 30;
|
||||||
|
|
||||||
public static final int wallpapersDidLoaded = 171;
|
public static final int wallpapersDidLoaded = 171;
|
||||||
public static final int closeOtherAppActivities = 702;
|
public static final int closeOtherAppActivities = 702;
|
||||||
|
@ -52,6 +53,9 @@ public class NotificationCenter {
|
||||||
public static final int FileLoadProgressChanged = 10003;
|
public static final int FileLoadProgressChanged = 10003;
|
||||||
public static final int FileDidLoaded = 10004;
|
public static final int FileDidLoaded = 10004;
|
||||||
public static final int FileDidFailedLoad = 10005;
|
public static final int FileDidFailedLoad = 10005;
|
||||||
|
public static final int FilePreparingStarted = 10006;
|
||||||
|
public static final int FileNewChunkAvailable = 10007;
|
||||||
|
public static final int FilePreparingFailed = 10008;
|
||||||
|
|
||||||
public final static int audioProgressDidChanged = 50001;
|
public final static int audioProgressDidChanged = 50001;
|
||||||
public final static int audioDidReset = 50002;
|
public final static int audioDidReset = 50002;
|
||||||
|
|
|
@ -60,7 +60,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
public SendMessagesHelper() {
|
public SendMessagesHelper() {
|
||||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidUpload);
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidUpload);
|
||||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailUpload);
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailUpload);
|
||||||
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FilePreparingStarted);
|
||||||
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileNewChunkAvailable);
|
||||||
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FilePreparingFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
|
@ -72,10 +74,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
currentChatInfo = info;
|
currentChatInfo = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessageSent(Integer id) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void didReceivedNotification(int id, Object... args) {
|
public void didReceivedNotification(int id, Object... args) {
|
||||||
if (id == NotificationCenter.FileDidUpload) {
|
if (id == NotificationCenter.FileDidUpload) {
|
||||||
|
@ -102,19 +100,23 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
media.file = file;
|
media.file = file;
|
||||||
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
||||||
} else if (message.type == 1) {
|
} else if (message.type == 1) {
|
||||||
if (media.thumb == null) {
|
if (media.file == null) {
|
||||||
media.thumb = file;
|
media.file = file;
|
||||||
performSendDelayedMessage(message);
|
performSendDelayedMessage(message);
|
||||||
} else {
|
} else {
|
||||||
media.file = file;
|
media.thumb = file;
|
||||||
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
||||||
}
|
}
|
||||||
} else if (message.type == 2) {
|
} else if (message.type == 2) {
|
||||||
if (media.thumb == null && message.location != null) {
|
if (media.file == null) {
|
||||||
media.thumb = file;
|
|
||||||
performSendDelayedMessage(message);
|
|
||||||
} else {
|
|
||||||
media.file = file;
|
media.file = file;
|
||||||
|
if (media.thumb == null && message.location != null) {
|
||||||
|
performSendDelayedMessage(message);
|
||||||
|
} else {
|
||||||
|
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
media.thumb = file;
|
||||||
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
performSendMessageRequest(message.sendRequest, message.obj, message.originalPath);
|
||||||
}
|
}
|
||||||
} else if (message.type == 3) {
|
} else if (message.type == 3) {
|
||||||
|
@ -163,6 +165,72 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (id == NotificationCenter.FilePreparingStarted) {
|
||||||
|
MessageObject messageObject = (MessageObject)args[0];
|
||||||
|
String finalPath = (String)args[1];
|
||||||
|
|
||||||
|
ArrayList<DelayedMessage> arr = delayedMessages.get(messageObject.messageOwner.attachPath);
|
||||||
|
if (arr != null) {
|
||||||
|
for (int a = 0; a < arr.size(); a++) {
|
||||||
|
DelayedMessage message = arr.get(a);
|
||||||
|
if (message.obj == messageObject) {
|
||||||
|
message.videoLocation.videoEditedInfo = null;
|
||||||
|
performSendDelayedMessage(message);
|
||||||
|
arr.remove(a);
|
||||||
|
a--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (arr.isEmpty()) {
|
||||||
|
delayedMessages.remove(messageObject.messageOwner.attachPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (id == NotificationCenter.FileNewChunkAvailable) {
|
||||||
|
MessageObject messageObject = (MessageObject)args[0];
|
||||||
|
String finalPath = (String)args[1];
|
||||||
|
long finalSize = (Long)args[2];
|
||||||
|
boolean isEncrypted = ((int)messageObject.getDialogId()) == 0;
|
||||||
|
FileLoader.getInstance().checkUploadNewDataAvailable(finalPath, isEncrypted, finalSize);
|
||||||
|
if (finalSize != 0) {
|
||||||
|
ArrayList<DelayedMessage> arr = delayedMessages.get(messageObject.messageOwner.attachPath);
|
||||||
|
if (arr != null) {
|
||||||
|
for (DelayedMessage message : arr) {
|
||||||
|
if (message.obj == messageObject) {
|
||||||
|
message.obj.messageOwner.videoEditedInfo = null;
|
||||||
|
message.obj.messageOwner.message = "-1";
|
||||||
|
|
||||||
|
ArrayList<TLRPC.Message> messages = new ArrayList<TLRPC.Message>();
|
||||||
|
messages.add(message.obj.messageOwner);
|
||||||
|
MessagesStorage.getInstance().putMessages(messages, false, true, false, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (arr.isEmpty()) {
|
||||||
|
delayedMessages.remove(messageObject.messageOwner.attachPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (id == NotificationCenter.FilePreparingFailed) {
|
||||||
|
MessageObject messageObject = (MessageObject)args[0];
|
||||||
|
String finalPath = (String)args[1];
|
||||||
|
|
||||||
|
ArrayList<DelayedMessage> arr = delayedMessages.get(finalPath);
|
||||||
|
if (arr != null) {
|
||||||
|
for (int a = 0; a < arr.size(); a++) {
|
||||||
|
DelayedMessage message = arr.get(a);
|
||||||
|
if (message.obj == messageObject) {
|
||||||
|
MessagesStorage.getInstance().markMessageAsSendError(message.obj.messageOwner.id);
|
||||||
|
message.obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
||||||
|
arr.remove(a);
|
||||||
|
a--;
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, message.obj.messageOwner.id);
|
||||||
|
processSentMessage(message.obj.messageOwner.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (arr.isEmpty()) {
|
||||||
|
delayedMessages.remove(finalPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +243,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
DelayedMessage message = messages.get(a);
|
DelayedMessage message = messages.get(a);
|
||||||
if (message.obj.messageOwner.id == object.messageOwner.id) {
|
if (message.obj.messageOwner.id == object.messageOwner.id) {
|
||||||
messages.remove(a);
|
messages.remove(a);
|
||||||
|
MediaController.getInstance().cancelVideoConvert(message.obj);
|
||||||
if (messages.size() == 0) {
|
if (messages.size() == 0) {
|
||||||
keyToRemvoe = entry.getKey();
|
keyToRemvoe = entry.getKey();
|
||||||
if (message.sendEncryptedRequest != null) {
|
if (message.sendEncryptedRequest != null) {
|
||||||
|
@ -204,7 +273,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processSentMessage(int id) {
|
public void processSentMessage(int id) {
|
||||||
int prevSize = unsentMessages.size();
|
int prevSize = unsentMessages.size();
|
||||||
unsentMessages.remove(id);
|
unsentMessages.remove(id);
|
||||||
if (prevSize != 0 && unsentMessages.size() == 0) {
|
if (prevSize != 0 && unsentMessages.size() == 0) {
|
||||||
|
@ -220,14 +289,13 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
if (messageObject.messageOwner.media.photo instanceof TLRPC.TL_photo) {
|
if (messageObject.messageOwner.media.photo instanceof TLRPC.TL_photo) {
|
||||||
sendMessage((TLRPC.TL_photo) messageObject.messageOwner.media.photo, null, did);
|
sendMessage((TLRPC.TL_photo) messageObject.messageOwner.media.photo, null, did);
|
||||||
} else if (messageObject.messageOwner.media.audio instanceof TLRPC.TL_audio) {
|
} else if (messageObject.messageOwner.media.audio instanceof TLRPC.TL_audio) {
|
||||||
messageObject.messageOwner.media.audio.path = messageObject.messageOwner.attachPath;
|
sendMessage((TLRPC.TL_audio) messageObject.messageOwner.media.audio, messageObject.messageOwner.attachPath, did);
|
||||||
sendMessage((TLRPC.TL_audio) messageObject.messageOwner.media.audio, did);
|
|
||||||
} else if (messageObject.messageOwner.media.video instanceof TLRPC.TL_video) {
|
} else if (messageObject.messageOwner.media.video instanceof TLRPC.TL_video) {
|
||||||
messageObject.messageOwner.media.video.path = messageObject.messageOwner.attachPath;
|
TLRPC.TL_video video = (TLRPC.TL_video) messageObject.messageOwner.media.video;
|
||||||
sendMessage((TLRPC.TL_video) messageObject.messageOwner.media.video, null, did);
|
video.videoEditedInfo = messageObject.messageOwner.videoEditedInfo;
|
||||||
|
sendMessage(video, null, messageObject.messageOwner.attachPath, did);
|
||||||
} else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_document) {
|
} else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_document) {
|
||||||
messageObject.messageOwner.media.document.path = messageObject.messageOwner.attachPath;
|
sendMessage((TLRPC.TL_document) messageObject.messageOwner.media.document, null, messageObject.messageOwner.attachPath, did);
|
||||||
sendMessage((TLRPC.TL_document) messageObject.messageOwner.media.document, null, did);
|
|
||||||
} else if (messageObject.messageOwner.media.geo instanceof TLRPC.TL_geoPoint) {
|
} else if (messageObject.messageOwner.media.geo instanceof TLRPC.TL_geoPoint) {
|
||||||
sendMessage(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long, did);
|
sendMessage(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long, did);
|
||||||
} else if (messageObject.messageOwner.media.phone_number != null) {
|
} else if (messageObject.messageOwner.media.phone_number != null) {
|
||||||
|
@ -248,42 +316,42 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(TLRPC.User user, long peer) {
|
public void sendMessage(TLRPC.User user, long peer) {
|
||||||
sendMessage(null, 0, 0, null, null, null, user, null, null, null, peer, false);
|
sendMessage(null, 0, 0, null, null, null, user, null, null, null, peer, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(MessageObject message) {
|
public void sendMessage(MessageObject message) {
|
||||||
sendMessage(null, 0, 0, null, null, message, null, null, null, null, message.getDialogId(), true);
|
sendMessage(null, 0, 0, null, null, message, null, null, null, null, message.getDialogId(), true, message.messageOwner.attachPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(MessageObject message, long peer) {
|
public void sendMessage(MessageObject message, long peer) {
|
||||||
sendMessage(null, 0, 0, null, null, message, null, null, null, null, peer, false);
|
sendMessage(null, 0, 0, null, null, message, null, null, null, null, peer, false, message.messageOwner.attachPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(TLRPC.TL_document document, String originalPath, long peer) {
|
public void sendMessage(TLRPC.TL_document document, String originalPath, String path, long peer) {
|
||||||
sendMessage(null, 0, 0, null, null, null, null, document, null, originalPath, peer, false);
|
sendMessage(null, 0, 0, null, null, null, null, document, null, originalPath, peer, false, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(String message, long peer) {
|
public void sendMessage(String message, long peer) {
|
||||||
sendMessage(message, 0, 0, null, null, null, null, null, null, null, peer, false);
|
sendMessage(message, 0, 0, null, null, null, null, null, null, null, peer, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(double lat, double lon, long peer) {
|
public void sendMessage(double lat, double lon, long peer) {
|
||||||
sendMessage(null, lat, lon, null, null, null, null, null, null, null, peer, false);
|
sendMessage(null, lat, lon, null, null, null, null, null, null, null, peer, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(TLRPC.TL_photo photo, String originalPath, long peer) {
|
public void sendMessage(TLRPC.TL_photo photo, String originalPath, long peer) {
|
||||||
sendMessage(null, 0, 0, photo, null, null, null, null, null, originalPath, peer, false);
|
sendMessage(null, 0, 0, photo, null, null, null, null, null, originalPath, peer, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(TLRPC.TL_video video, String originalPath, long peer) {
|
public void sendMessage(TLRPC.TL_video video, String originalPath, String path, long peer) {
|
||||||
sendMessage(null, 0, 0, null, video, null, null, null, null, originalPath, peer, false);
|
sendMessage(null, 0, 0, null, video, null, null, null, null, originalPath, peer, false, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(TLRPC.TL_audio audio, long peer) {
|
public void sendMessage(TLRPC.TL_audio audio, String path, long peer) {
|
||||||
sendMessage(null, 0, 0, null, null, null, null, null, audio, null, peer, false);
|
sendMessage(null, 0, 0, null, null, null, null, null, audio, null, peer, false, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendMessage(String message, double lat, double lon, TLRPC.TL_photo photo, TLRPC.TL_video video, MessageObject msgObj, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, boolean retry) {
|
private int sendMessage(String message, double lat, double lon, TLRPC.TL_photo photo, TLRPC.TL_video video, MessageObject msgObj, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, boolean retry, String path) {
|
||||||
TLRPC.Message newMsg = null;
|
TLRPC.Message newMsg = null;
|
||||||
int type = -1;
|
int type = -1;
|
||||||
if (retry) {
|
if (retry) {
|
||||||
|
@ -313,7 +381,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
} else {
|
} else {
|
||||||
type = 3;
|
type = 3;
|
||||||
video = (TLRPC.TL_video) newMsg.media.video;
|
video = (TLRPC.TL_video) newMsg.media.video;
|
||||||
video.path = newMsg.attachPath;
|
video.videoEditedInfo = newMsg.videoEditedInfo;
|
||||||
}
|
}
|
||||||
} else if (msgObj.type == 12 || msgObj.type == 13) {
|
} else if (msgObj.type == 12 || msgObj.type == 13) {
|
||||||
user = new TLRPC.TL_userRequest();
|
user = new TLRPC.TL_userRequest();
|
||||||
|
@ -324,11 +392,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
type = 6;
|
type = 6;
|
||||||
} else if (msgObj.type == 8 || msgObj.type == 9) {
|
} else if (msgObj.type == 8 || msgObj.type == 9) {
|
||||||
document = (TLRPC.TL_document) newMsg.media.document;
|
document = (TLRPC.TL_document) newMsg.media.document;
|
||||||
document.path = newMsg.attachPath;
|
|
||||||
type = 7;
|
type = 7;
|
||||||
} else if (msgObj.type == 2) {
|
} else if (msgObj.type == 2) {
|
||||||
audio = (TLRPC.TL_audio) newMsg.media.audio;
|
audio = (TLRPC.TL_audio) newMsg.media.audio;
|
||||||
audio.path = newMsg.attachPath;
|
|
||||||
type = 8;
|
type = 8;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -357,9 +423,14 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
newMsg = new TLRPC.TL_message();
|
newMsg = new TLRPC.TL_message();
|
||||||
newMsg.media = new TLRPC.TL_messageMediaVideo();
|
newMsg.media = new TLRPC.TL_messageMediaVideo();
|
||||||
newMsg.media.video = video;
|
newMsg.media.video = video;
|
||||||
|
newMsg.videoEditedInfo = video.videoEditedInfo;
|
||||||
type = 3;
|
type = 3;
|
||||||
newMsg.message = "-1";
|
if (video.videoEditedInfo == null) {
|
||||||
newMsg.attachPath = video.path;
|
newMsg.message = "-1";
|
||||||
|
} else {
|
||||||
|
newMsg.message = video.videoEditedInfo.getString();
|
||||||
|
}
|
||||||
|
newMsg.attachPath = path;
|
||||||
} else if (msgObj != null) {
|
} else if (msgObj != null) {
|
||||||
newMsg = new TLRPC.TL_messageForwarded();
|
newMsg = new TLRPC.TL_messageForwarded();
|
||||||
if (msgObj.messageOwner instanceof TLRPC.TL_messageForwarded) {
|
if (msgObj.messageOwner instanceof TLRPC.TL_messageForwarded) {
|
||||||
|
@ -394,14 +465,14 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
newMsg.media.document = document;
|
newMsg.media.document = document;
|
||||||
type = 7;
|
type = 7;
|
||||||
newMsg.message = "-1";
|
newMsg.message = "-1";
|
||||||
newMsg.attachPath = document.path;
|
newMsg.attachPath = path;
|
||||||
} else if (audio != null) {
|
} else if (audio != null) {
|
||||||
newMsg = new TLRPC.TL_message();
|
newMsg = new TLRPC.TL_message();
|
||||||
newMsg.media = new TLRPC.TL_messageMediaAudio();
|
newMsg.media = new TLRPC.TL_messageMediaAudio();
|
||||||
newMsg.media.audio = audio;
|
newMsg.media.audio = audio;
|
||||||
type = 8;
|
type = 8;
|
||||||
newMsg.message = "-1";
|
newMsg.message = "-1";
|
||||||
newMsg.attachPath = audio.path;
|
newMsg.attachPath = path;
|
||||||
}
|
}
|
||||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
||||||
newMsg.from_id = UserConfig.getClientUserId();
|
newMsg.from_id = UserConfig.getClientUserId();
|
||||||
|
@ -423,7 +494,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
if (high_id == 1) {
|
if (high_id == 1) {
|
||||||
if (currentChatInfo == null) {
|
if (currentChatInfo == null) {
|
||||||
processSentMessage(newMsg.id);
|
processSentMessage(newMsg.id);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
sendToPeers = new ArrayList<TLRPC.InputUser>();
|
sendToPeers = new ArrayList<TLRPC.InputUser>();
|
||||||
for (TLRPC.TL_chatParticipant participant : currentChatInfo.participants) {
|
for (TLRPC.TL_chatParticipant participant : currentChatInfo.participants) {
|
||||||
|
@ -448,7 +519,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
TLRPC.User sendToUser = MessagesController.getInstance().getUser(lower_id);
|
TLRPC.User sendToUser = MessagesController.getInstance().getUser(lower_id);
|
||||||
if (sendToUser == null) {
|
if (sendToUser == null) {
|
||||||
processSentMessage(newMsg.id);
|
processSentMessage(newMsg.id);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (sendToUser instanceof TLRPC.TL_userForeign || sendToUser instanceof TLRPC.TL_userRequest) {
|
if (sendToUser instanceof TLRPC.TL_userForeign || sendToUser instanceof TLRPC.TL_userRequest) {
|
||||||
sendToPeer = new TLRPC.TL_inputPeerForeign();
|
sendToPeer = new TLRPC.TL_inputPeerForeign();
|
||||||
|
@ -782,7 +853,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id);
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id);
|
||||||
processSentMessage(newMsgObj.messageOwner.id);
|
processSentMessage(newMsgObj.messageOwner.id);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
return newMsg != null ? newMsg.id : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performSendDelayedMessage(final DelayedMessage message) {
|
private void performSendDelayedMessage(final DelayedMessage message) {
|
||||||
|
@ -795,63 +868,78 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
FileLoader.getInstance().uploadFile(location, true, true);
|
FileLoader.getInstance().uploadFile(location, true, true);
|
||||||
}
|
}
|
||||||
} else if (message.type == 1) {
|
} else if (message.type == 1) {
|
||||||
if (message.sendRequest != null) {
|
if (message.videoLocation.videoEditedInfo != null) {
|
||||||
TLRPC.InputMedia media = null;
|
String location = message.obj.messageOwner.attachPath;
|
||||||
if (message.sendRequest instanceof TLRPC.TL_messages_sendMedia) {
|
|
||||||
media = ((TLRPC.TL_messages_sendMedia)message.sendRequest).media;
|
|
||||||
} else if (message.sendRequest instanceof TLRPC.TL_messages_sendBroadcast) {
|
|
||||||
media = ((TLRPC.TL_messages_sendBroadcast)message.sendRequest).media;
|
|
||||||
}
|
|
||||||
if (media.thumb == null) {
|
|
||||||
String location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.location.volume_id + "_" + message.location.local_id + ".jpg";
|
|
||||||
putToDelayedMessages(location, message);
|
|
||||||
FileLoader.getInstance().uploadFile(location, false, true);
|
|
||||||
} else {
|
|
||||||
String location = message.videoLocation.path;
|
|
||||||
if (location == null) {
|
|
||||||
location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.videoLocation.id + ".mp4";
|
|
||||||
}
|
|
||||||
putToDelayedMessages(location, message);
|
|
||||||
if (message.videoLocation.estimatedSize) {
|
|
||||||
FileLoader.getInstance().uploadFile(location, false, false, message.videoLocation.size);
|
|
||||||
} else {
|
|
||||||
FileLoader.getInstance().uploadFile(location, false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
String location = message.videoLocation.path;
|
|
||||||
if (location == null) {
|
if (location == null) {
|
||||||
location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.videoLocation.id + ".mp4";
|
location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.videoLocation.id + ".mp4";
|
||||||
}
|
}
|
||||||
putToDelayedMessages(location, message);
|
putToDelayedMessages(location, message);
|
||||||
if (message.videoLocation.estimatedSize) {
|
MediaController.getInstance().scheduleVideoConvert(message.obj);
|
||||||
FileLoader.getInstance().uploadFile(location, true, false, message.videoLocation.size);
|
} else {
|
||||||
|
if (message.sendRequest != null) {
|
||||||
|
TLRPC.InputMedia media = null;
|
||||||
|
if (message.sendRequest instanceof TLRPC.TL_messages_sendMedia) {
|
||||||
|
media = ((TLRPC.TL_messages_sendMedia) message.sendRequest).media;
|
||||||
|
} else if (message.sendRequest instanceof TLRPC.TL_messages_sendBroadcast) {
|
||||||
|
media = ((TLRPC.TL_messages_sendBroadcast) message.sendRequest).media;
|
||||||
|
}
|
||||||
|
if (media.file == null) {
|
||||||
|
String location = message.obj.messageOwner.attachPath;
|
||||||
|
if (location == null) {
|
||||||
|
location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.videoLocation.id + ".mp4";
|
||||||
|
}
|
||||||
|
putToDelayedMessages(location, message);
|
||||||
|
if (message.obj.messageOwner.videoEditedInfo != null) {
|
||||||
|
FileLoader.getInstance().uploadFile(location, false, false, message.videoLocation.size);
|
||||||
|
} else {
|
||||||
|
FileLoader.getInstance().uploadFile(location, false, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.location.volume_id + "_" + message.location.local_id + ".jpg";
|
||||||
|
putToDelayedMessages(location, message);
|
||||||
|
FileLoader.getInstance().uploadFile(location, false, true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
FileLoader.getInstance().uploadFile(location, true, false);
|
String location = message.obj.messageOwner.attachPath;
|
||||||
|
if (location == null) {
|
||||||
|
location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.videoLocation.id + ".mp4";
|
||||||
|
}
|
||||||
|
putToDelayedMessages(location, message);
|
||||||
|
if (message.videoLocation.videoEditedInfo != null) {
|
||||||
|
FileLoader.getInstance().uploadFile(location, true, false, message.videoLocation.size);
|
||||||
|
} else {
|
||||||
|
FileLoader.getInstance().uploadFile(location, true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (message.type == 2) {
|
} else if (message.type == 2) {
|
||||||
TLRPC.InputMedia media = null;
|
TLRPC.InputMedia media = null;
|
||||||
if (message.sendRequest instanceof TLRPC.TL_messages_sendMedia) {
|
if (message.sendRequest != null) {
|
||||||
media = ((TLRPC.TL_messages_sendMedia)message.sendRequest).media;
|
if (message.sendRequest instanceof TLRPC.TL_messages_sendMedia) {
|
||||||
} else if (message.sendRequest instanceof TLRPC.TL_messages_sendBroadcast) {
|
media = ((TLRPC.TL_messages_sendMedia) message.sendRequest).media;
|
||||||
media = ((TLRPC.TL_messages_sendBroadcast)message.sendRequest).media;
|
} else if (message.sendRequest instanceof TLRPC.TL_messages_sendBroadcast) {
|
||||||
}
|
media = ((TLRPC.TL_messages_sendBroadcast) message.sendRequest).media;
|
||||||
if (message.sendRequest != null && media.thumb == null && message.location != null) {
|
|
||||||
String location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.location.volume_id + "_" + message.location.local_id + ".jpg";
|
|
||||||
putToDelayedMessages(location, message);
|
|
||||||
FileLoader.getInstance().uploadFile(location, false, true);
|
|
||||||
} else {
|
|
||||||
String location = message.documentLocation.path;
|
|
||||||
putToDelayedMessages(location, message);
|
|
||||||
if (message.sendRequest != null) {
|
|
||||||
FileLoader.getInstance().uploadFile(location, false, false);
|
|
||||||
} else {
|
|
||||||
FileLoader.getInstance().uploadFile(location, true, false);
|
|
||||||
}
|
}
|
||||||
|
if (media.file == null) {
|
||||||
|
String location = message.obj.messageOwner.attachPath;
|
||||||
|
putToDelayedMessages(location, message);
|
||||||
|
if (message.sendRequest != null) {
|
||||||
|
FileLoader.getInstance().uploadFile(location, false, false);
|
||||||
|
} else {
|
||||||
|
FileLoader.getInstance().uploadFile(location, true, false);
|
||||||
|
}
|
||||||
|
} else if (media.thumb == null && message.location != null) {
|
||||||
|
String location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.location.volume_id + "_" + message.location.local_id + ".jpg";
|
||||||
|
putToDelayedMessages(location, message);
|
||||||
|
FileLoader.getInstance().uploadFile(location, false, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String location = message.obj.messageOwner.attachPath;
|
||||||
|
putToDelayedMessages(location, message);
|
||||||
|
FileLoader.getInstance().uploadFile(location, true, false);
|
||||||
}
|
}
|
||||||
} else if (message.type == 3) {
|
} else if (message.type == 3) {
|
||||||
String location = message.audioLocation.path;
|
String location = message.obj.messageOwner.attachPath;
|
||||||
putToDelayedMessages(location, message);
|
putToDelayedMessages(location, message);
|
||||||
if (message.sendRequest != null) {
|
if (message.sendRequest != null) {
|
||||||
FileLoader.getInstance().uploadFile(location, false, true);
|
FileLoader.getInstance().uploadFile(location, false, true);
|
||||||
|
@ -1187,7 +1275,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
newMsg.media.video.access_hash = file.access_hash;
|
newMsg.media.video.access_hash = file.access_hash;
|
||||||
newMsg.media.video.key = decryptedMessage.media.key;
|
newMsg.media.video.key = decryptedMessage.media.key;
|
||||||
newMsg.media.video.iv = decryptedMessage.media.iv;
|
newMsg.media.video.iv = decryptedMessage.media.iv;
|
||||||
newMsg.media.video.path = video.path;
|
|
||||||
newMsg.media.video.mime_type = video.mime_type;
|
newMsg.media.video.mime_type = video.mime_type;
|
||||||
ArrayList<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
|
ArrayList<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
|
||||||
arr.add(newMsg);
|
arr.add(newMsg);
|
||||||
|
@ -1206,12 +1293,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
newMsg.media.document.size = file.size;
|
newMsg.media.document.size = file.size;
|
||||||
newMsg.media.document.key = decryptedMessage.media.key;
|
newMsg.media.document.key = decryptedMessage.media.key;
|
||||||
newMsg.media.document.iv = decryptedMessage.media.iv;
|
newMsg.media.document.iv = decryptedMessage.media.iv;
|
||||||
newMsg.media.document.path = document.path;
|
|
||||||
newMsg.media.document.thumb = document.thumb;
|
newMsg.media.document.thumb = document.thumb;
|
||||||
newMsg.media.document.dc_id = file.dc_id;
|
newMsg.media.document.dc_id = file.dc_id;
|
||||||
|
|
||||||
if (document.path != null && document.path.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) {
|
if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) {
|
||||||
File cacheFile = new File(document.path);
|
File cacheFile = new File(newMsg.attachPath);
|
||||||
File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.document);
|
File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.document);
|
||||||
cacheFile.renameTo(cacheFile2);
|
cacheFile.renameTo(cacheFile2);
|
||||||
}
|
}
|
||||||
|
@ -1233,7 +1319,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
newMsg.media.audio.dc_id = file.dc_id;
|
newMsg.media.audio.dc_id = file.dc_id;
|
||||||
newMsg.media.audio.key = decryptedMessage.media.key;
|
newMsg.media.audio.key = decryptedMessage.media.key;
|
||||||
newMsg.media.audio.iv = decryptedMessage.media.iv;
|
newMsg.media.audio.iv = decryptedMessage.media.iv;
|
||||||
newMsg.media.audio.path = audio.path;
|
|
||||||
newMsg.media.audio.mime_type = audio.mime_type;
|
newMsg.media.audio.mime_type = audio.mime_type;
|
||||||
|
|
||||||
String fileName = audio.dc_id + "_" + audio.id + ".ogg";
|
String fileName = audio.dc_id + "_" + audio.id + ".ogg";
|
||||||
|
@ -1399,4 +1484,95 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
private void startConvert() throws Exception {
|
||||||
|
IsoFile isoFile = new IsoFile(videoPath);
|
||||||
|
TrackBox trackBox = (TrackBox) Path.getPath(isoFile, "/moov/trak/mdia/minf/stbl/stsd/avc1/../../../../../");
|
||||||
|
AvcConfigurationBox avcConfigurationBox = (AvcConfigurationBox) Path.getPath(trackBox, "mdia/minf/stbl/stsd/avc1/avcC");
|
||||||
|
avcConfigurationBox.parseDetails();
|
||||||
|
|
||||||
|
Movie movie = MovieCreator.build(videoPath);
|
||||||
|
|
||||||
|
List<Track> tracks = movie.getTracks();
|
||||||
|
movie.setTracks(new LinkedList<Track>());
|
||||||
|
|
||||||
|
double startTime = 0;
|
||||||
|
double endTime = 0;
|
||||||
|
|
||||||
|
for (Track track : tracks) {
|
||||||
|
if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
|
||||||
|
double duration = (double) track.getDuration() / (double) track.getTrackMetaData().getTimescale();
|
||||||
|
startTime = correctTimeToSyncSample(track, videoTimelineView.getLeftProgress() * duration, false);
|
||||||
|
endTime = videoTimelineView.getRightProgress() * duration;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Track track : tracks) {
|
||||||
|
long currentSample = 0;
|
||||||
|
double currentTime = 0;
|
||||||
|
double lastTime = 0;
|
||||||
|
long startSample = 0;
|
||||||
|
long endSample = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < track.getSampleDurations().length; i++) {
|
||||||
|
long delta = track.getSampleDurations()[i];
|
||||||
|
if (currentTime > lastTime && currentTime <= startTime) {
|
||||||
|
startSample = currentSample;
|
||||||
|
}
|
||||||
|
if (currentTime > lastTime && currentTime <= endTime) {
|
||||||
|
endSample = currentSample;
|
||||||
|
}
|
||||||
|
lastTime = currentTime;
|
||||||
|
currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale();
|
||||||
|
currentSample++;
|
||||||
|
}
|
||||||
|
movie.addTrack(new CroppedTrack(track, startSample, endSample));
|
||||||
|
}
|
||||||
|
Container out = new DefaultMp4Builder().build(movie);
|
||||||
|
|
||||||
|
String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4";
|
||||||
|
UserConfig.lastLocalId--;
|
||||||
|
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
|
||||||
|
UserConfig.saveConfig(false);
|
||||||
|
|
||||||
|
FileOutputStream fos = new FileOutputStream(cacheFile);
|
||||||
|
FileChannel fc = fos.getChannel();
|
||||||
|
out.writeContainer(fc);
|
||||||
|
|
||||||
|
fc.close();
|
||||||
|
fos.close();
|
||||||
|
if (delegate != null) {
|
||||||
|
//delegate.didFinishedVideoConverting(cacheFile.getAbsolutePath());
|
||||||
|
finishFragment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double correctTimeToSyncSample(Track track, double cutHere, boolean next) {
|
||||||
|
double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
|
||||||
|
long currentSample = 0;
|
||||||
|
double currentTime = 0;
|
||||||
|
for (int i = 0; i < track.getSampleDurations().length; i++) {
|
||||||
|
long delta = track.getSampleDurations()[i];
|
||||||
|
if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
|
||||||
|
timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime;
|
||||||
|
}
|
||||||
|
currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale();
|
||||||
|
currentSample++;
|
||||||
|
}
|
||||||
|
double previous = 0;
|
||||||
|
for (double timeOfSyncSample : timeOfSyncSamples) {
|
||||||
|
if (timeOfSyncSample > cutHere) {
|
||||||
|
if (next) {
|
||||||
|
return timeOfSyncSample;
|
||||||
|
} else {
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previous = timeOfSyncSample;
|
||||||
|
}
|
||||||
|
return timeOfSyncSamples[timeOfSyncSamples.length - 1];
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,14 @@ public class FileLoader {
|
||||||
public File getDirectory(int type) {
|
public File getDirectory(int type) {
|
||||||
File dir = mediaDirs.get(type);
|
File dir = mediaDirs.get(type);
|
||||||
if (dir == null && type != MEDIA_DIR_CACHE) {
|
if (dir == null && type != MEDIA_DIR_CACHE) {
|
||||||
return mediaDirs.get(MEDIA_DIR_CACHE);
|
dir = mediaDirs.get(MEDIA_DIR_CACHE);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (!dir.isDirectory()) {
|
||||||
|
dir.mkdirs();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
//don't promt
|
||||||
}
|
}
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
@ -588,6 +595,16 @@ public class FileLoader {
|
||||||
return new File("");
|
return new File("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File getExistPathToAttach(TLObject attach) {
|
||||||
|
File path = getInstance().getDirectory(MEDIA_DIR_CACHE);
|
||||||
|
String fileName = getAttachFileName(attach);
|
||||||
|
File attachPath = new File(path, fileName);
|
||||||
|
if (attachPath.exists()) {
|
||||||
|
return attachPath;
|
||||||
|
}
|
||||||
|
return getPathToAttach(attach);
|
||||||
|
}
|
||||||
|
|
||||||
public static File getPathToAttach(TLObject attach) {
|
public static File getPathToAttach(TLObject attach) {
|
||||||
File dir = null;
|
File dir = null;
|
||||||
if (attach instanceof TLRPC.Video) {
|
if (attach instanceof TLRPC.Video) {
|
||||||
|
|
|
@ -42,8 +42,9 @@ public class FileUploadOperation {
|
||||||
private boolean isBigFile = false;
|
private boolean isBigFile = false;
|
||||||
private String fileKey;
|
private String fileKey;
|
||||||
private int estimatedSize = 0;
|
private int estimatedSize = 0;
|
||||||
FileInputStream stream;
|
private int uploadStartTime = 0;
|
||||||
MessageDigest mdEnc = null;
|
private FileInputStream stream;
|
||||||
|
private MessageDigest mdEnc = null;
|
||||||
|
|
||||||
public static interface FileUploadOperationDelegate {
|
public static interface FileUploadOperationDelegate {
|
||||||
public abstract void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile);
|
public abstract void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile);
|
||||||
|
@ -93,14 +94,16 @@ public class FileUploadOperation {
|
||||||
remove(fileKey + "_ivc").commit();
|
remove(fileKey + "_ivc").commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkNewDataAvailable(final long finalSize) {
|
protected void checkNewDataAvailable(final long finalSize) {
|
||||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (finalSize != 0) {
|
if (estimatedSize != 0 && finalSize != 0) {
|
||||||
estimatedSize = 0;
|
estimatedSize = 0;
|
||||||
totalFileSize = finalSize;
|
totalFileSize = finalSize;
|
||||||
totalPartsCount = (int) Math.ceil((float) totalFileSize / (float) uploadChunkSize);
|
totalPartsCount = (int) Math.ceil((float) totalFileSize / (float) uploadChunkSize);
|
||||||
|
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE);
|
||||||
|
storeFileUploadInfo(preferences);
|
||||||
}
|
}
|
||||||
if (requestToken == 0) {
|
if (requestToken == 0) {
|
||||||
startUploadRequest();
|
startUploadRequest();
|
||||||
|
@ -109,6 +112,20 @@ public class FileUploadOperation {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void storeFileUploadInfo(SharedPreferences preferences) {
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
editor.putInt(fileKey + "_time", uploadStartTime);
|
||||||
|
editor.putLong(fileKey + "_size", totalFileSize);
|
||||||
|
editor.putLong(fileKey + "_id", currentFileId);
|
||||||
|
editor.remove(fileKey + "_uploaded");
|
||||||
|
if (isEncrypted) {
|
||||||
|
editor.putString(fileKey + "_iv", Utilities.bytesToHex(iv));
|
||||||
|
editor.putString(fileKey + "_ivc", Utilities.bytesToHex(ivChange));
|
||||||
|
editor.putString(fileKey + "_key", Utilities.bytesToHex(key));
|
||||||
|
}
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
private void startUploadRequest() {
|
private void startUploadRequest() {
|
||||||
if (state != 1) {
|
if (state != 1) {
|
||||||
return;
|
return;
|
||||||
|
@ -151,7 +168,7 @@ public class FileUploadOperation {
|
||||||
fileKey = Utilities.MD5(uploadingFilePath + (isEncrypted ? "enc" : ""));
|
fileKey = Utilities.MD5(uploadingFilePath + (isEncrypted ? "enc" : ""));
|
||||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE);
|
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE);
|
||||||
long fileSize = preferences.getLong(fileKey + "_size", 0);
|
long fileSize = preferences.getLong(fileKey + "_size", 0);
|
||||||
int currentTime = (int)(System.currentTimeMillis() / 1000);
|
uploadStartTime = (int)(System.currentTimeMillis() / 1000);
|
||||||
boolean rewrite = false;
|
boolean rewrite = false;
|
||||||
if (estimatedSize == 0 && fileSize == totalFileSize) {
|
if (estimatedSize == 0 && fileSize == totalFileSize) {
|
||||||
currentFileId = preferences.getLong(fileKey + "_id", 0);
|
currentFileId = preferences.getLong(fileKey + "_id", 0);
|
||||||
|
@ -170,9 +187,9 @@ public class FileUploadOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!rewrite && date != 0) {
|
if (!rewrite && date != 0) {
|
||||||
if (isBigFile && date < currentTime - 60 * 60 * 24) {
|
if (isBigFile && date < uploadStartTime - 60 * 60 * 24) {
|
||||||
date = 0;
|
date = 0;
|
||||||
} else if (!isBigFile && date < currentTime - 60 * 60 * 1.5f) {
|
} else if (!isBigFile && date < uploadStartTime - 60 * 60 * 1.5f) {
|
||||||
date = 0;
|
date = 0;
|
||||||
}
|
}
|
||||||
if (date != 0) {
|
if (date != 0) {
|
||||||
|
@ -235,17 +252,7 @@ public class FileUploadOperation {
|
||||||
}
|
}
|
||||||
currentFileId = Utilities.random.nextLong();
|
currentFileId = Utilities.random.nextLong();
|
||||||
if (estimatedSize == 0) {
|
if (estimatedSize == 0) {
|
||||||
SharedPreferences.Editor editor = preferences.edit();
|
storeFileUploadInfo(preferences);
|
||||||
editor.putInt(fileKey + "_time", currentTime);
|
|
||||||
editor.putLong(fileKey + "_size", totalFileSize);
|
|
||||||
editor.putLong(fileKey + "_id", currentFileId);
|
|
||||||
editor.remove(fileKey + "_uploaded");
|
|
||||||
if (isEncrypted) {
|
|
||||||
editor.putString(fileKey + "_iv", Utilities.bytesToHex(iv));
|
|
||||||
editor.putString(fileKey + "_ivc", Utilities.bytesToHex(ivChange));
|
|
||||||
editor.putString(fileKey + "_key", Utilities.bytesToHex(key));
|
|
||||||
}
|
|
||||||
editor.commit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
package org.telegram.messenger;
|
package org.telegram.messenger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class TLRPC {
|
public class TLRPC {
|
||||||
|
@ -8539,6 +8540,7 @@ public class TLRPC {
|
||||||
public int local_id = 0;
|
public int local_id = 0;
|
||||||
public long dialog_id;
|
public long dialog_id;
|
||||||
public int ttl;
|
public int ttl;
|
||||||
|
public VideoEditedInfo videoEditedInfo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TL_messageForwarded extends Message {
|
public static class TL_messageForwarded extends Message {
|
||||||
|
@ -8559,9 +8561,13 @@ public class TLRPC {
|
||||||
if (id < 0) {
|
if (id < 0) {
|
||||||
fwd_msg_id = stream.readInt32();
|
fwd_msg_id = stream.readInt32();
|
||||||
}
|
}
|
||||||
if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.equals("-1"))) {
|
if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) {
|
||||||
attachPath = stream.readString();
|
attachPath = stream.readString();
|
||||||
}
|
}
|
||||||
|
if (id < 0 && message.length() > 6 && media instanceof TL_messageMediaVideo) {
|
||||||
|
videoEditedInfo = new VideoEditedInfo();
|
||||||
|
videoEditedInfo.parseString(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void serializeToStream(AbsSerializedData stream) {
|
public void serializeToStream(AbsSerializedData stream) {
|
||||||
|
@ -8595,9 +8601,13 @@ public class TLRPC {
|
||||||
date = stream.readInt32();
|
date = stream.readInt32();
|
||||||
message = stream.readString();
|
message = stream.readString();
|
||||||
media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||||
if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.equals("-1"))) {
|
if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) {
|
||||||
attachPath = stream.readString();
|
attachPath = stream.readString();
|
||||||
}
|
}
|
||||||
|
if (id < 0 && message.length() > 6 && media instanceof TL_messageMediaVideo) {
|
||||||
|
videoEditedInfo = new VideoEditedInfo();
|
||||||
|
videoEditedInfo.parseString(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void serializeToStream(AbsSerializedData stream) {
|
public void serializeToStream(AbsSerializedData stream) {
|
||||||
|
@ -8954,6 +8964,46 @@ public class TLRPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class VideoEditedInfo {
|
||||||
|
public long startTime;
|
||||||
|
public long endTime;
|
||||||
|
public int rotationValue;
|
||||||
|
public int originalWidth;
|
||||||
|
public int originalHeight;
|
||||||
|
public int resultWidth;
|
||||||
|
public int resultHeight;
|
||||||
|
public int bitrate;
|
||||||
|
public String originalPath;
|
||||||
|
|
||||||
|
public String getString() {
|
||||||
|
return String.format(Locale.US, "-1_%d_%d_%d_%d_%d_%d_%d_%d_%s", startTime, endTime, rotationValue, originalWidth, originalHeight, bitrate, resultWidth, resultHeight, originalPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parseString(String string) {
|
||||||
|
if (string.length() < 6) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String args[] = string.split("_");
|
||||||
|
if (args.length >= 10) {
|
||||||
|
startTime = Long.parseLong(args[1]);
|
||||||
|
endTime = Long.parseLong(args[2]);
|
||||||
|
rotationValue = Integer.parseInt(args[3]);
|
||||||
|
originalWidth = Integer.parseInt(args[4]);
|
||||||
|
originalHeight = Integer.parseInt(args[5]);
|
||||||
|
bitrate = Integer.parseInt(args[6]);
|
||||||
|
resultWidth = Integer.parseInt(args[7]);
|
||||||
|
resultHeight = Integer.parseInt(args[8]);
|
||||||
|
for (int a = 9; a < args.length; a++) {
|
||||||
|
if (originalPath == null) {
|
||||||
|
originalPath = args[a];
|
||||||
|
} else {
|
||||||
|
originalPath += "_" + args[a];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class Video extends TLObject {
|
public static class Video extends TLObject {
|
||||||
public long id;
|
public long id;
|
||||||
public long access_hash;
|
public long access_hash;
|
||||||
|
@ -8967,10 +9017,9 @@ public class TLRPC {
|
||||||
public int dc_id;
|
public int dc_id;
|
||||||
public int w;
|
public int w;
|
||||||
public int h;
|
public int h;
|
||||||
public String path;
|
|
||||||
public byte[] key;
|
public byte[] key;
|
||||||
public byte[] iv;
|
public byte[] iv;
|
||||||
public boolean estimatedSize;
|
public VideoEditedInfo videoEditedInfo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Document extends TLObject {
|
public static class Document extends TLObject {
|
||||||
|
@ -8983,7 +9032,6 @@ public class TLRPC {
|
||||||
public int size;
|
public int size;
|
||||||
public PhotoSize thumb;
|
public PhotoSize thumb;
|
||||||
public int dc_id;
|
public int dc_id;
|
||||||
public String path;
|
|
||||||
public byte[] key;
|
public byte[] key;
|
||||||
public byte[] iv;
|
public byte[] iv;
|
||||||
}
|
}
|
||||||
|
@ -8997,7 +9045,6 @@ public class TLRPC {
|
||||||
public String mime_type;
|
public String mime_type;
|
||||||
public int size;
|
public int size;
|
||||||
public int dc_id;
|
public int dc_id;
|
||||||
public String path;
|
|
||||||
public byte[] key;
|
public byte[] key;
|
||||||
public byte[] iv;
|
public byte[] iv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -564,17 +564,17 @@ public class ChatBaseCell extends BaseCell {
|
||||||
boolean drawError = false;
|
boolean drawError = false;
|
||||||
boolean isBroadcast = (int)(currentMessageObject.getDialogId() >> 32) == 1;
|
boolean isBroadcast = (int)(currentMessageObject.getDialogId() >> 32) == 1;
|
||||||
|
|
||||||
if (currentMessageObject.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
if (currentMessageObject.isSending()) {
|
||||||
drawCheck1 = false;
|
drawCheck1 = false;
|
||||||
drawCheck2 = false;
|
drawCheck2 = false;
|
||||||
drawClock = true;
|
drawClock = true;
|
||||||
drawError = false;
|
drawError = false;
|
||||||
} else if (currentMessageObject.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SEND_ERROR) {
|
} else if (currentMessageObject.isSendError()) {
|
||||||
drawCheck1 = false;
|
drawCheck1 = false;
|
||||||
drawCheck2 = false;
|
drawCheck2 = false;
|
||||||
drawClock = false;
|
drawClock = false;
|
||||||
drawError = true;
|
drawError = true;
|
||||||
} else if (currentMessageObject.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENT) {
|
} else if (currentMessageObject.isSent()) {
|
||||||
if (!currentMessageObject.isUnread()) {
|
if (!currentMessageObject.isUnread()) {
|
||||||
drawCheck1 = true;
|
drawCheck1 = true;
|
||||||
drawCheck2 = true;
|
drawCheck2 = true;
|
||||||
|
|
|
@ -52,8 +52,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||||
private static Drawable videoIconDrawable;
|
private static Drawable videoIconDrawable;
|
||||||
private static Drawable docMenuInDrawable;
|
private static Drawable docMenuInDrawable;
|
||||||
private static Drawable docMenuOutDrawable;
|
private static Drawable docMenuOutDrawable;
|
||||||
private static Drawable[] buttonStatesDrawables = new Drawable[4];
|
private static Drawable[] buttonStatesDrawables = new Drawable[5];
|
||||||
private static Drawable[][] buttonStatesDrawablesDoc = new Drawable[2][2];
|
private static Drawable[][] buttonStatesDrawablesDoc = new Drawable[3][2];
|
||||||
private static TextPaint infoPaint;
|
private static TextPaint infoPaint;
|
||||||
private static MessageObject lastDownloadedGifMessage = null;
|
private static MessageObject lastDownloadedGifMessage = null;
|
||||||
private static TextPaint namePaint;
|
private static TextPaint namePaint;
|
||||||
|
@ -114,10 +114,13 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||||
buttonStatesDrawables[1] = getResources().getDrawable(R.drawable.photocancel);
|
buttonStatesDrawables[1] = getResources().getDrawable(R.drawable.photocancel);
|
||||||
buttonStatesDrawables[2] = getResources().getDrawable(R.drawable.photogif);
|
buttonStatesDrawables[2] = getResources().getDrawable(R.drawable.photogif);
|
||||||
buttonStatesDrawables[3] = getResources().getDrawable(R.drawable.playvideo);
|
buttonStatesDrawables[3] = getResources().getDrawable(R.drawable.playvideo);
|
||||||
|
buttonStatesDrawables[4] = getResources().getDrawable(R.drawable.photopause);
|
||||||
buttonStatesDrawablesDoc[0][0] = getResources().getDrawable(R.drawable.docload_b);
|
buttonStatesDrawablesDoc[0][0] = getResources().getDrawable(R.drawable.docload_b);
|
||||||
buttonStatesDrawablesDoc[1][0] = getResources().getDrawable(R.drawable.doccancel_b);
|
buttonStatesDrawablesDoc[1][0] = getResources().getDrawable(R.drawable.doccancel_b);
|
||||||
|
buttonStatesDrawablesDoc[2][0] = getResources().getDrawable(R.drawable.docpause_b);
|
||||||
buttonStatesDrawablesDoc[0][1] = getResources().getDrawable(R.drawable.docload_g);
|
buttonStatesDrawablesDoc[0][1] = getResources().getDrawable(R.drawable.docload_g);
|
||||||
buttonStatesDrawablesDoc[1][1] = getResources().getDrawable(R.drawable.doccancel_g);
|
buttonStatesDrawablesDoc[1][1] = getResources().getDrawable(R.drawable.doccancel_g);
|
||||||
|
buttonStatesDrawablesDoc[2][1] = getResources().getDrawable(R.drawable.docpause_g);
|
||||||
videoIconDrawable = getResources().getDrawable(R.drawable.ic_video);
|
videoIconDrawable = getResources().getDrawable(R.drawable.ic_video);
|
||||||
docMenuInDrawable = getResources().getDrawable(R.drawable.doc_actions_b);
|
docMenuInDrawable = getResources().getDrawable(R.drawable.doc_actions_b);
|
||||||
docMenuOutDrawable = getResources().getDrawable(R.drawable.doc_actions_g);
|
docMenuOutDrawable = getResources().getDrawable(R.drawable.doc_actions_g);
|
||||||
|
@ -172,7 +175,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||||
float y = event.getY();
|
float y = event.getY();
|
||||||
|
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
int side = AndroidUtilities.dp(44);
|
int side = AndroidUtilities.dp(48);
|
||||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
if (delegate == null || delegate.canPerformActions()) {
|
if (delegate == null || delegate.canPerformActions()) {
|
||||||
if (buttonState != -1 && x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) {
|
if (buttonState != -1 && x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) {
|
||||||
|
@ -321,7 +324,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||||
buttonState = 1;
|
buttonState = 1;
|
||||||
invalidate();
|
invalidate();
|
||||||
} else if (buttonState == 1) {
|
} else if (buttonState == 1) {
|
||||||
if (currentMessageObject.isOut() && currentMessageObject.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
if (currentMessageObject.isOut() && currentMessageObject.isSending()) {
|
||||||
if (delegate != null) {
|
if (delegate != null) {
|
||||||
delegate.didPressedCancelSendButton(this);
|
delegate.didPressedCancelSendButton(this);
|
||||||
}
|
}
|
||||||
|
@ -616,7 +619,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||||
if (fileName == null) {
|
if (fileName == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (currentMessageObject.isOut() && currentMessageObject.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
if (currentMessageObject.isOut() && currentMessageObject.isSending()) {
|
||||||
if (currentMessageObject.messageOwner.attachPath != null) {
|
if (currentMessageObject.messageOwner.attachPath != null) {
|
||||||
MediaController.getInstance().addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, this);
|
MediaController.getInstance().addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, this);
|
||||||
progressVisible = true;
|
progressVisible = true;
|
||||||
|
@ -709,7 +712,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invalidateProgress() {
|
private void invalidateProgress() {
|
||||||
int offset = AndroidUtilities.dp(1);
|
int offset = AndroidUtilities.dp(2);
|
||||||
invalidate((int)progressRect.left - offset, (int)progressRect.top - offset, (int)progressRect.right + offset * 2, (int)progressRect.bottom + offset * 2);
|
invalidate((int)progressRect.left - offset, (int)progressRect.top - offset, (int)progressRect.right + offset * 2, (int)progressRect.bottom + offset * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,10 +745,10 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
photoImage.setImageCoords(x, AndroidUtilities.dp(7), photoWidth, photoHeight);
|
photoImage.setImageCoords(x, AndroidUtilities.dp(7), photoWidth, photoHeight);
|
||||||
int size = AndroidUtilities.dp(44);
|
int size = AndroidUtilities.dp(48);
|
||||||
buttonX = (int)(x + (photoWidth - size) / 2.0f);
|
buttonX = (int)(x + (photoWidth - size) / 2.0f);
|
||||||
buttonY = (int)(AndroidUtilities.dp(7) + (photoHeight - size) / 2.0f);
|
buttonY = (int)(AndroidUtilities.dp(7) + (photoHeight - size) / 2.0f);
|
||||||
progressRect.set(buttonX + AndroidUtilities.dp(1), buttonY + AndroidUtilities.dp(1), buttonX + AndroidUtilities.dp(43), buttonY + AndroidUtilities.dp(43));
|
progressRect.set(buttonX + AndroidUtilities.dp(1), buttonY + AndroidUtilities.dp(1), buttonX + AndroidUtilities.dp(47), buttonY + AndroidUtilities.dp(47));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -783,7 +786,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||||
|
|
||||||
if (buttonState == -1) {
|
if (buttonState == -1) {
|
||||||
Drawable drawable = currentMessageObject.isOut() ? placeholderDocOutDrawable : placeholderDocInDrawable;
|
Drawable drawable = currentMessageObject.isOut() ? placeholderDocOutDrawable : placeholderDocInDrawable;
|
||||||
setDrawableBounds(drawable, photoImage.getImageX() + AndroidUtilities.dp(27), photoImage.getImageY() + AndroidUtilities.dp(27));
|
setDrawableBounds(drawable, photoImage.getImageX() + AndroidUtilities.dp(19), photoImage.getImageY() + AndroidUtilities.dp(19));
|
||||||
drawable.draw(canvas);
|
drawable.draw(canvas);
|
||||||
}
|
}
|
||||||
if (currentMessageObject.isOut()) {
|
if (currentMessageObject.isOut()) {
|
||||||
|
@ -802,9 +805,17 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||||
if (buttonState >= 0 && buttonState < 4) {
|
if (buttonState >= 0 && buttonState < 4) {
|
||||||
Drawable currentButtonDrawable = null;
|
Drawable currentButtonDrawable = null;
|
||||||
if (currentMessageObject.type == 9 && !imageDrawn) {
|
if (currentMessageObject.type == 9 && !imageDrawn) {
|
||||||
currentButtonDrawable = buttonStatesDrawablesDoc[buttonState][currentMessageObject.isOut() ? 1 : 0];
|
if (buttonState == 1 && !currentMessageObject.isSending()) {
|
||||||
|
currentButtonDrawable = buttonStatesDrawablesDoc[2][currentMessageObject.isOut() ? 1 : 0];
|
||||||
|
} else {
|
||||||
|
currentButtonDrawable = buttonStatesDrawablesDoc[buttonState][currentMessageObject.isOut() ? 1 : 0];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
currentButtonDrawable = buttonStatesDrawables[buttonState];
|
if (buttonState == 1 && !currentMessageObject.isSending()) {
|
||||||
|
currentButtonDrawable = buttonStatesDrawables[4];
|
||||||
|
} else {
|
||||||
|
currentButtonDrawable = buttonStatesDrawables[buttonState];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setDrawableBounds(currentButtonDrawable, buttonX, buttonY);
|
setDrawableBounds(currentButtonDrawable, buttonX, buttonY);
|
||||||
currentButtonDrawable.draw(canvas);
|
currentButtonDrawable.draw(canvas);
|
||||||
|
|
|
@ -528,18 +528,18 @@ public class DialogCell extends BaseCell {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.isFromMe() && message.isOut()) {
|
if (message.isFromMe() && message.isOut()) {
|
||||||
if (message.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
if (message.isSending()) {
|
||||||
drawCheck1 = false;
|
drawCheck1 = false;
|
||||||
drawCheck2 = false;
|
drawCheck2 = false;
|
||||||
drawClock = true;
|
drawClock = true;
|
||||||
drawError = false;
|
drawError = false;
|
||||||
} else if (message.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SEND_ERROR) {
|
} else if (message.isSendError()) {
|
||||||
drawCheck1 = false;
|
drawCheck1 = false;
|
||||||
drawCheck2 = false;
|
drawCheck2 = false;
|
||||||
drawClock = false;
|
drawClock = false;
|
||||||
drawError = true;
|
drawError = true;
|
||||||
drawCount = false;
|
drawCount = false;
|
||||||
} else if (message.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENT) {
|
} else if (message.isSent()) {
|
||||||
if (!message.isUnread()) {
|
if (!message.isUnread()) {
|
||||||
drawCheck1 = true;
|
drawCheck1 = true;
|
||||||
drawCheck2 = true;
|
drawCheck2 = true;
|
||||||
|
|
|
@ -21,6 +21,7 @@ import android.content.res.Configuration;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.media.MediaMetadataRetriever;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.media.ThumbnailUtils;
|
import android.media.ThumbnailUtils;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
@ -1072,9 +1073,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
|
|
||||||
private int getMessageType(MessageObject messageObject) {
|
private int getMessageType(MessageObject messageObject) {
|
||||||
if (currentEncryptedChat == null) {
|
if (currentEncryptedChat == null) {
|
||||||
boolean isBroadcastError = isBraodcast && messageObject.messageOwner.id <= 0 && messageObject.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
boolean isBroadcastError = isBraodcast && messageObject.messageOwner.id <= 0 && messageObject.isSendError();
|
||||||
if (!isBraodcast && messageObject.messageOwner.id <= 0 && messageObject.isOut() || isBroadcastError) {
|
if (!isBraodcast && messageObject.messageOwner.id <= 0 && messageObject.isOut() || isBroadcastError) {
|
||||||
if (messageObject.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SEND_ERROR) {
|
if (messageObject.isSendError()) {
|
||||||
if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) {
|
if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1128,13 +1129,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
} else {
|
} else {
|
||||||
if (messageObject.type == 6) {
|
if (messageObject.type == 6) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (messageObject.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SEND_ERROR) {
|
} else if (messageObject.isSendError()) {
|
||||||
if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) {
|
if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
} else if (messageObject.type == 10 || messageObject.type == 11 || messageObject.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
} else if (messageObject.type == 10 || messageObject.type == 11 || messageObject.isSending()) {
|
||||||
if (messageObject.messageOwner.id == 0) {
|
if (messageObject.messageOwner.id == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1243,6 +1244,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
}
|
}
|
||||||
|
|
||||||
CharSequence printString = MessagesController.getInstance().printingStrings.get(dialog_id);
|
CharSequence printString = MessagesController.getInstance().printingStrings.get(dialog_id);
|
||||||
|
if (printString != null) {
|
||||||
|
printString = TextUtils.replace(printString, new String[]{"..."}, new String[]{""});
|
||||||
|
}
|
||||||
if (printString == null || printString.length() == 0) {
|
if (printString == null || printString.length() == 0) {
|
||||||
lastPrintString = null;
|
lastPrintString = null;
|
||||||
setTypingAnimation(false);
|
setTypingAnimation(false);
|
||||||
|
@ -1362,7 +1366,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
fragment.setDelegate(this);
|
fragment.setDelegate(this);
|
||||||
presentFragment(fragment);
|
presentFragment(fragment);
|
||||||
} else {
|
} else {
|
||||||
processSendingVideo(videoPath, null, 0, 0, 0, 0);
|
processSendingVideo(videoPath, 0, 0, 0, 0, null);
|
||||||
}
|
}
|
||||||
} else if (requestCode == 21) {
|
} else if (requestCode == 21) {
|
||||||
if (data == null || data.getData() == null) {
|
if (data == null || data.getData() == null) {
|
||||||
|
@ -1385,13 +1389,18 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void didStartVideoConverting(String videoPath, String originalPath, long esimatedSize, int duration, int width, int height) {
|
public void didFinishEditVideo(String videoPath, long startTime, long endTime, int resultWidth, int resultHeight, int rotationValue, int originalWidth, int originalHeight, int bitrate, long estimatedSize, long estimatedDuration) {
|
||||||
processSendingVideo(videoPath, originalPath, esimatedSize, duration, width, height);
|
TLRPC.VideoEditedInfo videoEditedInfo = new TLRPC.VideoEditedInfo();
|
||||||
}
|
videoEditedInfo.startTime = startTime;
|
||||||
|
videoEditedInfo.endTime = endTime;
|
||||||
@Override
|
videoEditedInfo.rotationValue = rotationValue;
|
||||||
public void didAppenedVideoData(String videoPath, long finalSize) {
|
videoEditedInfo.originalWidth = originalWidth;
|
||||||
FileLoader.getInstance().checkUploadNewDataAvailable(videoPath, currentEncryptedChat != null, finalSize);
|
videoEditedInfo.originalHeight = originalHeight;
|
||||||
|
videoEditedInfo.bitrate = bitrate;
|
||||||
|
videoEditedInfo.resultWidth = resultWidth;
|
||||||
|
videoEditedInfo.resultHeight = resultHeight;
|
||||||
|
videoEditedInfo.originalPath = videoPath;
|
||||||
|
processSendingVideo(videoPath, estimatedSize, estimatedDuration, resultWidth, resultHeight, videoEditedInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showAttachmentError() {
|
private void showAttachmentError() {
|
||||||
|
@ -1525,7 +1534,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processSendingDocumentInternal(String path, String originalPath) {
|
private void processSendingDocumentInternal(final String path, String originalPath) {
|
||||||
if (path == null || path.length() == 0) {
|
if (path == null || path.length() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1586,14 +1595,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
document.thumb.type = "s";
|
document.thumb.type = "s";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.path = path;
|
|
||||||
|
|
||||||
final TLRPC.TL_document documentFinal = document;
|
final TLRPC.TL_document documentFinal = document;
|
||||||
final String originalPathFinal = originalPath;
|
final String originalPathFinal = originalPath;
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
SendMessagesHelper.getInstance().sendMessage(documentFinal, originalPathFinal, dialog_id);
|
SendMessagesHelper.getInstance().sendMessage(documentFinal, originalPathFinal, path, dialog_id);
|
||||||
if (chatListView != null) {
|
if (chatListView != null) {
|
||||||
chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop());
|
chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop());
|
||||||
}
|
}
|
||||||
|
@ -1629,29 +1637,23 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processSendingVideo(final String videoPath, final String originalFile, final long estimatedSize, final int duration, final int width, final int height) {
|
public void processSendingVideo(final String videoPath, final long estimatedSize, final long duration, final int width, final int height, final TLRPC.VideoEditedInfo videoEditedInfo) {
|
||||||
if (videoPath == null || videoPath.length() == 0) {
|
if (videoPath == null || videoPath.length() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
String originalPath = null;
|
String path = videoPath;
|
||||||
if (originalFile != null) {
|
String originalPath = videoPath;
|
||||||
originalPath = originalFile;
|
|
||||||
} else {
|
|
||||||
originalPath = videoPath;
|
|
||||||
}
|
|
||||||
File temp = new File(originalPath);
|
File temp = new File(originalPath);
|
||||||
originalPath += temp.length() + "_" + temp.lastModified();
|
originalPath += temp.length() + "_" + temp.lastModified();
|
||||||
TLRPC.TL_video video = null;// (TLRPC.TL_video)MessagesStorage.getInstance().getSentFile(originalPath, currentEncryptedChat == null ? 2 : 5);
|
if (videoEditedInfo != null) {
|
||||||
|
originalPath += duration + "_" + videoEditedInfo.startTime + "_" + videoEditedInfo.endTime;
|
||||||
|
}
|
||||||
|
TLRPC.TL_video video = (TLRPC.TL_video)MessagesStorage.getInstance().getSentFile(originalPath, currentEncryptedChat == null ? 2 : 5);
|
||||||
if (video == null) {
|
if (video == null) {
|
||||||
Bitmap thumb = null;
|
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Video.Thumbnails.MINI_KIND);
|
||||||
if (originalFile != null) {
|
|
||||||
thumb = ThumbnailUtils.createVideoThumbnail(originalFile, MediaStore.Video.Thumbnails.MINI_KIND);
|
|
||||||
} else {
|
|
||||||
thumb = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Video.Thumbnails.MINI_KIND);
|
|
||||||
}
|
|
||||||
TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(thumb, 90, 90, 55, currentEncryptedChat != null);
|
TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(thumb, 90, 90, 55, currentEncryptedChat != null);
|
||||||
if (size == null) {
|
if (size == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -1662,39 +1664,64 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
video.caption = "";
|
video.caption = "";
|
||||||
video.mime_type = "video/mp4";
|
video.mime_type = "video/mp4";
|
||||||
video.id = 0;
|
video.id = 0;
|
||||||
if (estimatedSize != 0) {
|
UserConfig.saveConfig(false);
|
||||||
|
|
||||||
|
if (videoEditedInfo != null) {
|
||||||
|
video.duration = (int)(duration / 1000);
|
||||||
|
if (videoEditedInfo.rotationValue == 90 || videoEditedInfo.rotationValue == 270) {
|
||||||
|
video.w = height;
|
||||||
|
video.h = width;
|
||||||
|
} else {
|
||||||
|
video.w = width;
|
||||||
|
video.h = height;
|
||||||
|
}
|
||||||
video.size = (int)estimatedSize;
|
video.size = (int)estimatedSize;
|
||||||
|
video.videoEditedInfo = videoEditedInfo;
|
||||||
|
String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4";
|
||||||
|
UserConfig.lastLocalId--;
|
||||||
|
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
|
||||||
|
UserConfig.saveConfig(false);
|
||||||
|
path = cacheFile.getAbsolutePath();
|
||||||
} else {
|
} else {
|
||||||
if (temp != null && temp.exists()) {
|
if (temp != null && temp.exists()) {
|
||||||
video.size = (int) temp.length();
|
video.size = (int) temp.length();
|
||||||
}
|
}
|
||||||
}
|
if (Build.VERSION.SDK_INT >= 10) {
|
||||||
UserConfig.saveConfig(false);
|
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
|
||||||
|
mediaMetadataRetriever.setDataSource(videoPath);
|
||||||
if (duration != 0) {
|
String width = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
|
||||||
video.duration = duration / 1000;
|
if (width != null) {
|
||||||
video.w = width;
|
video.w = Integer.parseInt(width);
|
||||||
video.h = height;
|
}
|
||||||
video.estimatedSize = true;
|
String height = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
|
||||||
} else {
|
if (height != null) {
|
||||||
MediaPlayer mp = MediaPlayer.create(ApplicationLoader.applicationContext, Uri.fromFile(new File(videoPath)));
|
video.h = Integer.parseInt(height);
|
||||||
if (mp == null) {
|
}
|
||||||
return;
|
String duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
|
||||||
|
if (duration != null) {
|
||||||
|
video.duration = (int) Math.ceil(Long.parseLong(duration) / 1000.0f);
|
||||||
|
}
|
||||||
|
mediaMetadataRetriever.release();
|
||||||
|
} else {
|
||||||
|
MediaPlayer mp = MediaPlayer.create(ApplicationLoader.applicationContext, Uri.fromFile(new File(videoPath)));
|
||||||
|
if (mp == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
video.duration = (int) Math.ceil(mp.getDuration() / 1000.0f);
|
||||||
|
video.w = mp.getVideoWidth();
|
||||||
|
video.h = mp.getVideoHeight();
|
||||||
|
mp.release();
|
||||||
}
|
}
|
||||||
video.duration = (int) Math.ceil(mp.getDuration() / 1000.0f);
|
|
||||||
video.w = mp.getVideoWidth();
|
|
||||||
video.h = mp.getVideoHeight();
|
|
||||||
mp.release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
video.path = videoPath;
|
|
||||||
|
|
||||||
final TLRPC.TL_video videoFinal = video;
|
final TLRPC.TL_video videoFinal = video;
|
||||||
final String originalPathFinal = originalPath;
|
final String originalPathFinal = originalPath;
|
||||||
|
final String finalPath = path;
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
SendMessagesHelper.getInstance().sendMessage(videoFinal, originalPathFinal, dialog_id);
|
SendMessagesHelper.getInstance().sendMessage(videoFinal, originalPathFinal, finalPath, dialog_id);
|
||||||
if (chatListView != null) {
|
if (chatListView != null) {
|
||||||
chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop());
|
chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop());
|
||||||
}
|
}
|
||||||
|
@ -1989,7 +2016,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
if (currentEncryptedChat != null && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageActionTTLChange && timerButton != null) {
|
if (currentEncryptedChat != null && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageActionTTLChange && timerButton != null) {
|
||||||
timerButton.setTime(obj.messageOwner.action.ttl);
|
timerButton.setTime(obj.messageOwner.action.ttl);
|
||||||
}
|
}
|
||||||
if (obj.isOut() && obj.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
if (obj.isOut() && obj.isSending()) {
|
||||||
scrollToLastMessage();
|
scrollToLastMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3300,10 +3327,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
@Override
|
@Override
|
||||||
public void didPressedImage(ChatMediaCell cell) {
|
public void didPressedImage(ChatMediaCell cell) {
|
||||||
MessageObject message = cell.getMessageObject();
|
MessageObject message = cell.getMessageObject();
|
||||||
if (message.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SEND_ERROR) {
|
if (message.isSendError()) {
|
||||||
createMenu(cell, false);
|
createMenu(cell, false);
|
||||||
return;
|
return;
|
||||||
} else if (message.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
} else if (message.isSending()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (message.type == 1) {
|
if (message.type == 1) {
|
||||||
|
@ -3553,17 +3580,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||||
|
|
||||||
if (message.isFromMe()) {
|
if (message.isFromMe()) {
|
||||||
if (halfCheckImage != null) {
|
if (halfCheckImage != null) {
|
||||||
if (message.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENDING) {
|
if (message.isSending()) {
|
||||||
checkImage.setVisibility(View.INVISIBLE);
|
checkImage.setVisibility(View.INVISIBLE);
|
||||||
halfCheckImage.setImageResource(R.drawable.msg_clock);
|
halfCheckImage.setImageResource(R.drawable.msg_clock);
|
||||||
halfCheckImage.setVisibility(View.VISIBLE);
|
halfCheckImage.setVisibility(View.VISIBLE);
|
||||||
} else if (message.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SEND_ERROR) {
|
} else if (message.isSendError()) {
|
||||||
halfCheckImage.setVisibility(View.VISIBLE);
|
halfCheckImage.setVisibility(View.VISIBLE);
|
||||||
halfCheckImage.setImageResource(R.drawable.msg_warning);
|
halfCheckImage.setImageResource(R.drawable.msg_warning);
|
||||||
if (checkImage != null) {
|
if (checkImage != null) {
|
||||||
checkImage.setVisibility(View.INVISIBLE);
|
checkImage.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
} else if (message.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENT) {
|
} else if (message.isSent()) {
|
||||||
if (!message.messageOwner.unread) {
|
if (!message.messageOwner.unread) {
|
||||||
halfCheckImage.setVisibility(View.VISIBLE);
|
halfCheckImage.setVisibility(View.VISIBLE);
|
||||||
checkImage.setVisibility(View.VISIBLE);
|
checkImage.setVisibility(View.VISIBLE);
|
||||||
|
|
|
@ -115,7 +115,35 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
shadowTablet.setOnTouchListener(new View.OnTouchListener() {
|
shadowTablet.setOnTouchListener(new View.OnTouchListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
return true;
|
if (!actionBarLayout.fragmentsStack.isEmpty() && event.getAction() == MotionEvent.ACTION_UP) {
|
||||||
|
float x = event.getX();
|
||||||
|
float y = event.getY();
|
||||||
|
int location[] = new int[2];
|
||||||
|
layersActionBarLayout.getLocationOnScreen(location);
|
||||||
|
int viewX = location[0];
|
||||||
|
int viewY = location[1];
|
||||||
|
|
||||||
|
if (x > viewX && x < viewX + layersActionBarLayout.getWidth() && y > viewY && y < viewY + layersActionBarLayout.getHeight()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (!layersActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) {
|
||||||
|
layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0));
|
||||||
|
a--;
|
||||||
|
}
|
||||||
|
layersActionBarLayout.closeLastFragment(true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
shadowTablet.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -514,7 +542,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putInt("user_id", push_user_id);
|
args.putInt("user_id", push_user_id);
|
||||||
ChatActivity fragment = new ChatActivity(args);
|
ChatActivity fragment = new ChatActivity(args);
|
||||||
if (actionBarLayout.presentFragment(fragment, false, true)) {
|
if (actionBarLayout.presentFragment(fragment, false, true, true)) {
|
||||||
pushOpened = true;
|
pushOpened = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,14 +550,14 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putInt("chat_id", push_chat_id);
|
args.putInt("chat_id", push_chat_id);
|
||||||
ChatActivity fragment = new ChatActivity(args);
|
ChatActivity fragment = new ChatActivity(args);
|
||||||
if (actionBarLayout.presentFragment(fragment, false, true)) {
|
if (actionBarLayout.presentFragment(fragment, false, true, true)) {
|
||||||
pushOpened = true;
|
pushOpened = true;
|
||||||
}
|
}
|
||||||
} else if (push_enc_id != 0) {
|
} else if (push_enc_id != 0) {
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putInt("enc_id", push_enc_id);
|
args.putInt("enc_id", push_enc_id);
|
||||||
ChatActivity fragment = new ChatActivity(args);
|
ChatActivity fragment = new ChatActivity(args);
|
||||||
if (actionBarLayout.presentFragment(fragment, false, true)) {
|
if (actionBarLayout.presentFragment(fragment, false, true, true)) {
|
||||||
pushOpened = true;
|
pushOpened = true;
|
||||||
}
|
}
|
||||||
} else if (showDialogsList) {
|
} else if (showDialogsList) {
|
||||||
|
@ -541,28 +569,42 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
isNew = false;
|
isNew = false;
|
||||||
}
|
}
|
||||||
if (videoPath != null || photoPathsArray != null || sendingText != null || documentsPathsArray != null || contactsToSend != null) {
|
if (videoPath != null || photoPathsArray != null || sendingText != null || documentsPathsArray != null || contactsToSend != null) {
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats);
|
if (!AndroidUtilities.isTablet()) {
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats);
|
||||||
|
}
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putBoolean("onlySelect", true);
|
args.putBoolean("onlySelect", true);
|
||||||
args.putString("selectAlertString", LocaleController.getString("SendMessagesTo", R.string.SendMessagesTo));
|
args.putString("selectAlertString", LocaleController.getString("SendMessagesTo", R.string.SendMessagesTo));
|
||||||
MessagesActivity fragment = new MessagesActivity(args);
|
MessagesActivity fragment = new MessagesActivity(args);
|
||||||
fragment.setDelegate(this);
|
fragment.setDelegate(this);
|
||||||
actionBarLayout.presentFragment(fragment, false, true);
|
actionBarLayout.presentFragment(fragment, false, true, true);
|
||||||
pushOpened = true;
|
pushOpened = true;
|
||||||
if (PhotoViewer.getInstance().isVisible()) {
|
if (PhotoViewer.getInstance().isVisible()) {
|
||||||
PhotoViewer.getInstance().closePhoto(true);
|
PhotoViewer.getInstance().closePhoto(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (open_settings != 0) {
|
if (open_settings != 0) {
|
||||||
actionBarLayout.presentFragment(new SettingsActivity(), false, true);
|
actionBarLayout.presentFragment(new SettingsActivity(), false, true, true);
|
||||||
pushOpened = true;
|
pushOpened = true;
|
||||||
}
|
}
|
||||||
if (!pushOpened && !isNew) {
|
if (!pushOpened && !isNew) {
|
||||||
if (actionBarLayout.fragmentsStack.isEmpty()) {
|
if (AndroidUtilities.isTablet()) {
|
||||||
if (!UserConfig.isClientActivated()) {
|
if (UserConfig.isClientActivated()) {
|
||||||
actionBarLayout.addFragmentToStack(new LoginActivity());
|
if (actionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
actionBarLayout.addFragmentToStack(new MessagesActivity(null));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
actionBarLayout.addFragmentToStack(new MessagesActivity(null));
|
if (layersActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
layersActionBarLayout.addFragmentToStack(new LoginActivity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (actionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
if (!UserConfig.isClientActivated()) {
|
||||||
|
actionBarLayout.addFragmentToStack(new LoginActivity());
|
||||||
|
} else {
|
||||||
|
actionBarLayout.addFragmentToStack(new MessagesActivity(null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actionBarLayout.showLastFragment();
|
actionBarLayout.showLastFragment();
|
||||||
|
@ -589,7 +631,9 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putBoolean("scrollToTopOnResume", true);
|
args.putBoolean("scrollToTopOnResume", true);
|
||||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats);
|
if (!AndroidUtilities.isTablet()) {
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats);
|
||||||
|
}
|
||||||
if (lower_part != 0) {
|
if (lower_part != 0) {
|
||||||
if (high_id == 1) {
|
if (high_id == 1) {
|
||||||
args.putInt("chat_id", lower_part);
|
args.putInt("chat_id", lower_part);
|
||||||
|
@ -606,7 +650,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
ChatActivity fragment = new ChatActivity(args);
|
ChatActivity fragment = new ChatActivity(args);
|
||||||
actionBarLayout.presentFragment(fragment, true);
|
actionBarLayout.presentFragment(fragment, true);
|
||||||
if (videoPath != null) {
|
if (videoPath != null) {
|
||||||
fragment.processSendingVideo(videoPath, null, 0, 0, 0, 0);
|
fragment.processSendingVideo(videoPath, 0, 0, 0, 0, null);
|
||||||
}
|
}
|
||||||
if (sendingText != null) {
|
if (sendingText != null) {
|
||||||
fragment.processSendingText(sendingText);
|
fragment.processSendingText(sendingText);
|
||||||
|
@ -647,7 +691,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation) {
|
public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation) {
|
||||||
return actionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation);
|
return actionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void needLayout() {
|
public void needLayout() {
|
||||||
|
@ -680,18 +724,18 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
relativeLayoutParams.leftMargin = leftWidth;
|
relativeLayoutParams.leftMargin = leftWidth;
|
||||||
buttonLayoutTablet.setLayoutParams(relativeLayoutParams);
|
buttonLayoutTablet.setLayoutParams(relativeLayoutParams);
|
||||||
|
|
||||||
if (AndroidUtilities.isSmallTablet() && mainFragmentsStack.size() == 2) {
|
if (AndroidUtilities.isSmallTablet() && actionBarLayout.fragmentsStack.size() == 2) {
|
||||||
BaseFragment chatFragment = mainFragmentsStack.get(1);
|
BaseFragment chatFragment = actionBarLayout.fragmentsStack.get(1);
|
||||||
mainFragmentsStack.remove(1);
|
actionBarLayout.fragmentsStack.remove(1);
|
||||||
actionBarLayout.showLastFragment();
|
actionBarLayout.showLastFragment();
|
||||||
rightFragmentsStack.add(chatFragment);
|
rightActionBarLayout.fragmentsStack.add(chatFragment);
|
||||||
rightActionBarLayout.showLastFragment();
|
rightActionBarLayout.showLastFragment();
|
||||||
}
|
}
|
||||||
|
|
||||||
rightActionBarLayout.setVisibility(rightFragmentsStack.isEmpty() ? View.GONE : View.VISIBLE);
|
rightActionBarLayout.setVisibility(rightActionBarLayout.fragmentsStack.isEmpty() ? View.GONE : View.VISIBLE);
|
||||||
buttonLayoutTablet.setVisibility(!mainFragmentsStack.isEmpty() && rightFragmentsStack.isEmpty() ? View.VISIBLE : View.GONE);
|
buttonLayoutTablet.setVisibility(!actionBarLayout.fragmentsStack.isEmpty() && rightActionBarLayout.fragmentsStack.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
backgroundTablet.setVisibility(rightFragmentsStack.isEmpty() ? View.VISIBLE : View.GONE);
|
backgroundTablet.setVisibility(rightActionBarLayout.fragmentsStack.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
shadowTabletSide.setVisibility(!mainFragmentsStack.isEmpty() ? View.VISIBLE : View.GONE);
|
shadowTabletSide.setVisibility(!actionBarLayout.fragmentsStack.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
} else {
|
} else {
|
||||||
tabletFullSize = true;
|
tabletFullSize = true;
|
||||||
|
|
||||||
|
@ -702,13 +746,13 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
|
|
||||||
shadowTabletSide.setVisibility(View.GONE);
|
shadowTabletSide.setVisibility(View.GONE);
|
||||||
rightActionBarLayout.setVisibility(View.GONE);
|
rightActionBarLayout.setVisibility(View.GONE);
|
||||||
backgroundTablet.setVisibility(View.GONE);
|
backgroundTablet.setVisibility(!actionBarLayout.fragmentsStack.isEmpty() ? View.GONE : View.VISIBLE);
|
||||||
buttonLayoutTablet.setVisibility(View.GONE);
|
buttonLayoutTablet.setVisibility(View.GONE);
|
||||||
|
|
||||||
if (rightFragmentsStack.size() == 1) {
|
if (rightActionBarLayout.fragmentsStack.size() == 1) {
|
||||||
BaseFragment chatFragment = rightFragmentsStack.get(0);
|
BaseFragment chatFragment = rightActionBarLayout.fragmentsStack.get(0);
|
||||||
rightFragmentsStack.remove(0);
|
rightActionBarLayout.fragmentsStack.remove(0);
|
||||||
actionBarLayout.presentFragment(chatFragment, false, true);
|
actionBarLayout.presentFragment(chatFragment, false, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -831,8 +875,22 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
try {
|
try {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
if (!actionBarLayout.fragmentsStack.isEmpty()) {
|
BaseFragment lastFragment = null;
|
||||||
BaseFragment lastFragment = actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1);
|
if (AndroidUtilities.isTablet()) {
|
||||||
|
if (!layersActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
lastFragment = layersActionBarLayout.fragmentsStack.get(layersActionBarLayout.fragmentsStack.size() - 1);
|
||||||
|
} else if (!rightActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
lastFragment = rightActionBarLayout.fragmentsStack.get(rightActionBarLayout.fragmentsStack.size() - 1);
|
||||||
|
} else if (!actionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
lastFragment = actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!actionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
lastFragment = actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastFragment != null) {
|
||||||
Bundle args = lastFragment.getArguments();
|
Bundle args = lastFragment.getArguments();
|
||||||
if (lastFragment instanceof ChatActivity && args != null) {
|
if (lastFragment instanceof ChatActivity && args != null) {
|
||||||
outState.putBundle("args", args);
|
outState.putBundle("args", args);
|
||||||
|
@ -943,35 +1001,52 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
MessagesActivity messagesActivity = (MessagesActivity)fragment;
|
MessagesActivity messagesActivity = (MessagesActivity)fragment;
|
||||||
if (messagesActivity.getDelegate() == null && layout != actionBarLayout) {
|
if (messagesActivity.getDelegate() == null && layout != actionBarLayout) {
|
||||||
actionBarLayout.removeAllFragments();
|
actionBarLayout.removeAllFragments();
|
||||||
actionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation);
|
actionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation, false);
|
||||||
layersActionBarLayout.removeAllFragments();
|
layersActionBarLayout.removeAllFragments();
|
||||||
layersActionBarLayout.setVisibility(View.GONE);
|
layersActionBarLayout.setVisibility(View.GONE);
|
||||||
if (!tabletFullSize) {
|
if (!tabletFullSize) {
|
||||||
shadowTabletSide.setVisibility(View.VISIBLE);
|
shadowTabletSide.setVisibility(View.VISIBLE);
|
||||||
if (rightFragmentsStack.isEmpty()) {
|
if (rightActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
buttonLayoutTablet.setVisibility(View.VISIBLE);
|
buttonLayoutTablet.setVisibility(View.VISIBLE);
|
||||||
backgroundTablet.setVisibility(View.VISIBLE);
|
backgroundTablet.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (fragment instanceof ChatActivity) {
|
}
|
||||||
|
if (fragment instanceof ChatActivity) {
|
||||||
if (!tabletFullSize && layout != rightActionBarLayout) {
|
if (!tabletFullSize && layout != rightActionBarLayout) {
|
||||||
rightActionBarLayout.setVisibility(View.VISIBLE);
|
rightActionBarLayout.setVisibility(View.VISIBLE);
|
||||||
buttonLayoutTablet.setVisibility(View.GONE);
|
buttonLayoutTablet.setVisibility(View.GONE);
|
||||||
backgroundTablet.setVisibility(View.GONE);
|
backgroundTablet.setVisibility(View.GONE);
|
||||||
rightActionBarLayout.removeAllFragments();
|
rightActionBarLayout.removeAllFragments();
|
||||||
rightActionBarLayout.presentFragment(fragment, removeLast, true);
|
rightActionBarLayout.presentFragment(fragment, removeLast, true, false);
|
||||||
if (removeLast) {
|
if (!layersActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
layout.closeLastFragment(true);
|
for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) {
|
||||||
|
layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0));
|
||||||
|
a--;
|
||||||
|
}
|
||||||
|
layersActionBarLayout.closeLastFragment(true);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (tabletFullSize && layout != actionBarLayout) {
|
} else if (tabletFullSize && layout != actionBarLayout) {
|
||||||
actionBarLayout.presentFragment(fragment, false, forceWithoutAnimation);
|
actionBarLayout.presentFragment(fragment, actionBarLayout.fragmentsStack.size() > 1, forceWithoutAnimation, false);
|
||||||
if (removeLast) {
|
if (!layersActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
layout.closeLastFragment(true);
|
for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) {
|
||||||
|
layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0));
|
||||||
|
a--;
|
||||||
|
}
|
||||||
|
layersActionBarLayout.closeLastFragment(true);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
if (!layersActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) {
|
||||||
|
layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0));
|
||||||
|
a--;
|
||||||
|
}
|
||||||
|
layersActionBarLayout.closeLastFragment(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (layout != layersActionBarLayout) {
|
} else if (layout != layersActionBarLayout) {
|
||||||
layersActionBarLayout.setVisibility(View.VISIBLE);
|
layersActionBarLayout.setVisibility(View.VISIBLE);
|
||||||
|
@ -983,7 +1058,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
} else {
|
} else {
|
||||||
shadowTablet.setBackgroundColor(0x7F000000);
|
shadowTablet.setBackgroundColor(0x7F000000);
|
||||||
}
|
}
|
||||||
layersActionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation);
|
layersActionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1004,7 +1079,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
layersActionBarLayout.setVisibility(View.GONE);
|
layersActionBarLayout.setVisibility(View.GONE);
|
||||||
if (!tabletFullSize) {
|
if (!tabletFullSize) {
|
||||||
shadowTabletSide.setVisibility(View.VISIBLE);
|
shadowTabletSide.setVisibility(View.VISIBLE);
|
||||||
if (rightFragmentsStack.isEmpty()) {
|
if (rightActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
buttonLayoutTablet.setVisibility(View.VISIBLE);
|
buttonLayoutTablet.setVisibility(View.VISIBLE);
|
||||||
backgroundTablet.setVisibility(View.VISIBLE);
|
backgroundTablet.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
@ -1018,9 +1093,23 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
backgroundTablet.setVisibility(View.GONE);
|
backgroundTablet.setVisibility(View.GONE);
|
||||||
rightActionBarLayout.removeAllFragments();
|
rightActionBarLayout.removeAllFragments();
|
||||||
rightActionBarLayout.addFragmentToStack(fragment);
|
rightActionBarLayout.addFragmentToStack(fragment);
|
||||||
|
if (!layersActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) {
|
||||||
|
layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0));
|
||||||
|
a--;
|
||||||
|
}
|
||||||
|
layersActionBarLayout.closeLastFragment(true);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (tabletFullSize && layout != actionBarLayout) {
|
} else if (tabletFullSize && layout != actionBarLayout) {
|
||||||
actionBarLayout.addFragmentToStack(fragment);
|
actionBarLayout.addFragmentToStack(fragment);
|
||||||
|
if (!layersActionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) {
|
||||||
|
layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0));
|
||||||
|
a--;
|
||||||
|
}
|
||||||
|
layersActionBarLayout.closeLastFragment(true);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (layout != layersActionBarLayout) {
|
} else if (layout != layersActionBarLayout) {
|
||||||
|
@ -1054,6 +1143,10 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
buttonLayoutTablet.setVisibility(View.VISIBLE);
|
buttonLayoutTablet.setVisibility(View.VISIBLE);
|
||||||
backgroundTablet.setVisibility(View.VISIBLE);
|
backgroundTablet.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
} else if (layout == layersActionBarLayout && actionBarLayout.fragmentsStack.isEmpty()) {
|
||||||
|
onFinish();
|
||||||
|
finish();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (layout.fragmentsStack.size() <= 1) {
|
if (layout.fragmentsStack.size() <= 1) {
|
||||||
|
|
|
@ -288,6 +288,7 @@ public class PhotoCropActivity extends BaseFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onFragmentCreate() {
|
public boolean onFragmentCreate() {
|
||||||
|
swipeBackEnabled = false;
|
||||||
String photoPath = getArguments().getString("photoPath");
|
String photoPath = getArguments().getString("photoPath");
|
||||||
Uri photoUri = getArguments().getParcelable("photoUri");
|
Uri photoUri = getArguments().getParcelable("photoUri");
|
||||||
if (photoPath == null && photoUri == null) {
|
if (photoPath == null && photoUri == null) {
|
||||||
|
|
|
@ -645,7 +645,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MessageObject obj = imagesArr.get(currentIndex);
|
MessageObject obj = imagesArr.get(currentIndex);
|
||||||
if (obj.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENT) {
|
if (obj.isSent()) {
|
||||||
ArrayList<Integer> arr = new ArrayList<Integer>();
|
ArrayList<Integer> arr = new ArrayList<Integer>();
|
||||||
arr.add(obj.messageOwner.id);
|
arr.add(obj.messageOwner.id);
|
||||||
MessagesController.getInstance().deleteMessages(arr, null, null);
|
MessagesController.getInstance().deleteMessages(arr, null, null);
|
||||||
|
@ -1061,7 +1061,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (currentFileName.endsWith("mp4")) {
|
if (currentFileName.endsWith("mp4")) {
|
||||||
if (currentMessageObject.messageOwner.send_state != MessageObject.MESSAGE_SEND_STATE_SENDING && currentMessageObject.messageOwner.send_state != MessageObject.MESSAGE_SEND_STATE_SEND_ERROR) {
|
if (!currentMessageObject.isSending() && !currentMessageObject.isSendError()) {
|
||||||
currentOverlay.setVisibility(View.VISIBLE);
|
currentOverlay.setVisibility(View.VISIBLE);
|
||||||
boolean load = false;
|
boolean load = false;
|
||||||
if (currentMessageObject.messageOwner.attachPath != null && currentMessageObject.messageOwner.attachPath.length() != 0) {
|
if (currentMessageObject.messageOwner.attachPath != null && currentMessageObject.messageOwner.attachPath.length() != 0) {
|
||||||
|
@ -1393,7 +1393,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
|
||||||
if (currentThumb != null && imageReceiver == centerImage) {
|
if (currentThumb != null && imageReceiver == centerImage) {
|
||||||
placeHolder = currentThumb;
|
placeHolder = currentThumb;
|
||||||
}
|
}
|
||||||
imageReceiver.setImage(fileLocation, null, placeHolder != null ? new BitmapDrawable(null, placeHolder) : null, size[0]);
|
imageReceiver.setImage(fileLocation, null, placeHolder != null ? new BitmapDrawable(null, placeHolder) : null, 0);
|
||||||
} else {
|
} else {
|
||||||
imageReceiver.setImageBitmap(parentActivity.getResources().getDrawable(R.drawable.photoview_placeholder));
|
imageReceiver.setImageBitmap(parentActivity.getResources().getDrawable(R.drawable.photoview_placeholder));
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,7 @@ package org.telegram.ui;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.media.MediaCodec;
|
|
||||||
import android.media.MediaCodecInfo;
|
|
||||||
import android.media.MediaCodecList;
|
|
||||||
import android.media.MediaExtractor;
|
|
||||||
import android.media.MediaFormat;
|
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -32,31 +26,18 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import com.coremedia.iso.IsoFile;
|
import com.coremedia.iso.IsoFile;
|
||||||
import com.coremedia.iso.boxes.Box;
|
import com.coremedia.iso.boxes.Box;
|
||||||
import com.coremedia.iso.boxes.Container;
|
|
||||||
import com.coremedia.iso.boxes.MediaBox;
|
import com.coremedia.iso.boxes.MediaBox;
|
||||||
import com.coremedia.iso.boxes.MediaHeaderBox;
|
import com.coremedia.iso.boxes.MediaHeaderBox;
|
||||||
import com.coremedia.iso.boxes.SampleSizeBox;
|
import com.coremedia.iso.boxes.SampleSizeBox;
|
||||||
import com.coremedia.iso.boxes.TrackBox;
|
import com.coremedia.iso.boxes.TrackBox;
|
||||||
import com.coremedia.iso.boxes.TrackHeaderBox;
|
import com.coremedia.iso.boxes.TrackHeaderBox;
|
||||||
import com.coremedia.iso.boxes.h264.AvcConfigurationBox;
|
|
||||||
import com.googlecode.mp4parser.authoring.Movie;
|
|
||||||
import com.googlecode.mp4parser.authoring.Track;
|
|
||||||
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
|
|
||||||
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
|
|
||||||
import com.googlecode.mp4parser.authoring.tracks.CroppedTrack;
|
|
||||||
import com.googlecode.mp4parser.util.Matrix;
|
import com.googlecode.mp4parser.util.Matrix;
|
||||||
import com.googlecode.mp4parser.util.Path;
|
import com.googlecode.mp4parser.util.Path;
|
||||||
|
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
import org.telegram.android.LocaleController;
|
import org.telegram.android.LocaleController;
|
||||||
import org.telegram.android.video.InputSurface;
|
|
||||||
import org.telegram.android.video.MP4Builder;
|
|
||||||
import org.telegram.android.video.Mp4Movie;
|
|
||||||
import org.telegram.android.video.OutputSurface;
|
|
||||||
import org.telegram.messenger.FileLoader;
|
|
||||||
import org.telegram.messenger.FileLog;
|
import org.telegram.messenger.FileLog;
|
||||||
import org.telegram.messenger.R;
|
import org.telegram.messenger.R;
|
||||||
import org.telegram.messenger.UserConfig;
|
|
||||||
import org.telegram.messenger.Utilities;
|
import org.telegram.messenger.Utilities;
|
||||||
import org.telegram.ui.Views.ActionBar.ActionBarLayer;
|
import org.telegram.ui.Views.ActionBar.ActionBarLayer;
|
||||||
import org.telegram.ui.Views.ActionBar.ActionBarMenu;
|
import org.telegram.ui.Views.ActionBar.ActionBarMenu;
|
||||||
|
@ -65,11 +46,6 @@ import org.telegram.ui.Views.VideoSeekBarView;
|
||||||
import org.telegram.ui.Views.VideoTimelineView;
|
import org.telegram.ui.Views.VideoTimelineView;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@TargetApi(16)
|
@TargetApi(16)
|
||||||
|
@ -80,10 +56,6 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
private final static int OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03;
|
private final static int OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03;
|
||||||
private final static int OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002;
|
private final static int OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002;
|
||||||
private final static int OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m = 0x7FA30C04;
|
private final static int OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m = 0x7FA30C04;
|
||||||
private final static String MIME_TYPE = "video/avc";
|
|
||||||
|
|
||||||
private final static int PROCESSOR_TYPE_OTHER = 0;
|
|
||||||
private final static int PROCESSOR_TYPE_QCOM = 1;
|
|
||||||
|
|
||||||
private MediaPlayer videoPlayer = null;
|
private MediaPlayer videoPlayer = null;
|
||||||
private VideoTimelineView videoTimelineView = null;
|
private VideoTimelineView videoTimelineView = null;
|
||||||
|
@ -95,14 +67,15 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
private VideoSeekBarView videoSeekBarView = null;
|
private VideoSeekBarView videoSeekBarView = null;
|
||||||
private TextureView textureView = null;
|
private TextureView textureView = null;
|
||||||
private View controlView = null;
|
private View controlView = null;
|
||||||
|
private boolean playerPrepared = false;
|
||||||
|
|
||||||
private String videoPath = null;
|
private String videoPath = null;
|
||||||
private float lastProgress = 0;
|
private float lastProgress = 0;
|
||||||
private boolean needSeek = false;
|
private boolean needSeek = false;
|
||||||
private VideoEditorActivityDelegate delegate;
|
private VideoEditorActivityDelegate delegate;
|
||||||
|
|
||||||
private boolean firstWrite = true;
|
private final Object sync = new Object();
|
||||||
//MediaMetadataRetriever TODO
|
private Thread thread = null;
|
||||||
|
|
||||||
private int rotationValue = 0;
|
private int rotationValue = 0;
|
||||||
private int originalWidth = 0;
|
private int originalWidth = 0;
|
||||||
|
@ -119,14 +92,17 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
private long esimatedDuration = 0;
|
private long esimatedDuration = 0;
|
||||||
|
|
||||||
public interface VideoEditorActivityDelegate {
|
public interface VideoEditorActivityDelegate {
|
||||||
public abstract void didStartVideoConverting(String videoPath, String originalPath, long estimatedSize, int duration, int width, int height);
|
public abstract void didFinishEditVideo(String videoPath, long startTime, long endTime, int resultWidth, int resultHeight, int rotationValue, int originalWidth, int originalHeight, int bitrate, long estimatedSize, long estimatedDuration);
|
||||||
public abstract void didAppenedVideoData(String videoPath, long finalSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable progressRunnable = new Runnable() {
|
private Runnable progressRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (videoPlayer != null && videoPlayer.isPlaying()) {
|
boolean playerCheck = false;
|
||||||
|
synchronized (sync) {
|
||||||
|
playerCheck = videoPlayer != null && videoPlayer.isPlaying();
|
||||||
|
}
|
||||||
|
while (playerCheck) {
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -160,6 +136,9 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
synchronized (sync) {
|
||||||
|
thread = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -185,6 +164,20 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
videoPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||||
|
@Override
|
||||||
|
public void onPrepared(MediaPlayer mp) {
|
||||||
|
playerPrepared = true;
|
||||||
|
videoPlayer.seekTo((int) (videoTimelineView.getLeftProgress() * videoDuration));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
videoPlayer.setDataSource(videoPath);
|
||||||
|
videoPlayer.prepareAsync();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
|
|
||||||
return super.onFragmentCreate();
|
return super.onFragmentCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,21 +202,21 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
if (id == -1) {
|
if (id == -1) {
|
||||||
finishFragment();
|
finishFragment();
|
||||||
} else if (id == 1) {
|
} else if (id == 1) {
|
||||||
if (videoPlayer != null) {
|
synchronized (sync) {
|
||||||
try {
|
if (videoPlayer != null) {
|
||||||
videoPlayer.stop();
|
try {
|
||||||
videoPlayer.release();
|
videoPlayer.stop();
|
||||||
videoPlayer = null;
|
videoPlayer.release();
|
||||||
} catch (Exception e) {
|
videoPlayer = null;
|
||||||
FileLog.e("tmessages", e);
|
} catch (Exception e) {
|
||||||
|
FileLog.e("tmessages", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
if (delegate != null) {
|
||||||
//startConvert();
|
delegate.didFinishEditVideo(videoPath, startTime, endTime, resultWidth, resultHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration);
|
||||||
VideoEditWrapper.runTest(VideoEditorActivity.this);
|
|
||||||
} catch (Exception e) {
|
|
||||||
FileLog.e("tmessages", e);
|
|
||||||
}
|
}
|
||||||
|
finishFragment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -250,7 +243,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
videoTimelineView.setDelegate(new VideoTimelineView.VideoTimelineViewDelegate() {
|
videoTimelineView.setDelegate(new VideoTimelineView.VideoTimelineViewDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public void onLeftProgressChanged(float progress) {
|
public void onLeftProgressChanged(float progress) {
|
||||||
if (videoPlayer == null) {
|
if (videoPlayer == null || !playerPrepared) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -270,7 +263,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRifhtProgressChanged(float progress) {
|
public void onRifhtProgressChanged(float progress) {
|
||||||
if (videoPlayer == null) {
|
if (videoPlayer == null || !playerPrepared) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -293,7 +286,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
videoSeekBarView.delegate = new VideoSeekBarView.SeekBarDelegate() {
|
videoSeekBarView.delegate = new VideoSeekBarView.SeekBarDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public void onSeekBarDrag(float progress) {
|
public void onSeekBarDrag(float progress) {
|
||||||
if (videoPlayer == null) {
|
if (videoPlayer == null || !playerPrepared) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (videoPlayer.isPlaying()) {
|
if (videoPlayer.isPlaying()) {
|
||||||
|
@ -353,9 +346,9 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
try {
|
try {
|
||||||
Surface s = new Surface(surface);
|
Surface s = new Surface(surface);
|
||||||
videoPlayer.setSurface(s);
|
videoPlayer.setSurface(s);
|
||||||
videoPlayer.setDataSource(videoPath);
|
if (playerPrepared) {
|
||||||
videoPlayer.prepare();
|
videoPlayer.seekTo((int) (videoTimelineView.getLeftProgress() * videoDuration));
|
||||||
videoPlayer.seekTo((int) (videoTimelineView.getLeftProgress() * videoDuration));
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
|
@ -400,8 +393,9 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
int width = rotationValue == 90 || rotationValue == 270 ? originalHeight : originalWidth;
|
int width = rotationValue == 90 || rotationValue == 270 ? originalHeight : originalWidth;
|
||||||
int height = rotationValue == 90 || rotationValue == 270 ? originalWidth : originalHeight;
|
int height = rotationValue == 90 || rotationValue == 270 ? originalWidth : originalHeight;
|
||||||
String videoDimension = String.format("%dx%d", width, height);
|
String videoDimension = String.format("%dx%d", width, height);
|
||||||
int minutes = (int)(videoDuration / 1000 / 60);
|
long duration = (long)Math.ceil(videoDuration);
|
||||||
int seconds = (int) Math.ceil(videoDuration / 1000) - minutes * 60;
|
int minutes = (int)(duration / 1000 / 60);
|
||||||
|
int seconds = (int) Math.ceil(duration / 1000) - minutes * 60;
|
||||||
String videoTimeSize = String.format("%d:%02d, %s", minutes, seconds, Utilities.formatFileSize(file.length()));
|
String videoTimeSize = String.format("%d:%02d, %s", minutes, seconds, Utilities.formatFileSize(file.length()));
|
||||||
originalSizeTextView.setText(String.format("%s, %s", videoDimension, videoTimeSize));
|
originalSizeTextView.setText(String.format("%s, %s", videoDimension, videoTimeSize));
|
||||||
}
|
}
|
||||||
|
@ -414,7 +408,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
int height = rotationValue == 90 || rotationValue == 270 ? resultWidth : resultHeight;
|
int height = rotationValue == 90 || rotationValue == 270 ? resultWidth : resultHeight;
|
||||||
String videoDimension = String.format("%dx%d", width, height);
|
String videoDimension = String.format("%dx%d", width, height);
|
||||||
|
|
||||||
esimatedDuration = (long)Math.max(1000, (videoTimelineView.getRightProgress() - videoTimelineView.getLeftProgress()) * videoDuration);
|
esimatedDuration = (long)Math.ceil((videoTimelineView.getRightProgress() - videoTimelineView.getLeftProgress()) * videoDuration);
|
||||||
estimatedSize = calculateEstimatedSize((float)esimatedDuration / videoDuration);
|
estimatedSize = calculateEstimatedSize((float)esimatedDuration / videoDuration);
|
||||||
if (videoTimelineView.getLeftProgress() == 0) {
|
if (videoTimelineView.getLeftProgress() == 0) {
|
||||||
startTime = -1;
|
startTime = -1;
|
||||||
|
@ -546,7 +540,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
}
|
}
|
||||||
|
|
||||||
private void play() {
|
private void play() {
|
||||||
if (videoPlayer == null) {
|
if (videoPlayer == null || !playerPrepared) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (videoPlayer.isPlaying()) {
|
if (videoPlayer.isPlaying()) {
|
||||||
|
@ -576,7 +570,12 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
videoPlayer.start();
|
videoPlayer.start();
|
||||||
new Thread(progressRunnable).start();
|
synchronized (sync) {
|
||||||
|
if (thread != null) {
|
||||||
|
thread = new Thread(progressRunnable);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
}
|
}
|
||||||
|
@ -587,170 +586,6 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int selectTrack(MediaExtractor extractor, boolean audio) {
|
|
||||||
int numTracks = extractor.getTrackCount();
|
|
||||||
for (int i = 0; i < numTracks; i++) {
|
|
||||||
MediaFormat format = extractor.getTrackFormat(i);
|
|
||||||
String mime = format.getString(MediaFormat.KEY_MIME);
|
|
||||||
if (audio) {
|
|
||||||
if (mime.startsWith("audio/")) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (mime.startsWith("video/")) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class VideoEditWrapper implements Runnable {
|
|
||||||
private VideoEditorActivity mTest;
|
|
||||||
private VideoEditWrapper(VideoEditorActivity test) {
|
|
||||||
mTest = test;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mTest.startConvert2();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void runTest(final VideoEditorActivity obj) {
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
VideoEditWrapper wrapper = new VideoEditWrapper(obj);
|
|
||||||
Thread th = new Thread(wrapper, "encoder");
|
|
||||||
th.start();
|
|
||||||
th.join();
|
|
||||||
} catch (Exception e) {
|
|
||||||
FileLog.e("tmessages", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void didWriteData(final String videoPath, final long finalSize) {
|
|
||||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (firstWrite) {
|
|
||||||
int width = rotationValue == 90 || rotationValue == 270 ? resultHeight : resultWidth;
|
|
||||||
int height = rotationValue == 90 || rotationValue == 270 ? resultWidth : resultHeight;
|
|
||||||
delegate.didStartVideoConverting(videoPath, VideoEditorActivity.this.videoPath, estimatedSize, (int)esimatedDuration, width, height);
|
|
||||||
firstWrite = false;
|
|
||||||
finishFragment();
|
|
||||||
} else {
|
|
||||||
delegate.didAppenedVideoData(videoPath, finalSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MediaCodecInfo selectCodec(String mimeType) {
|
|
||||||
int numCodecs = MediaCodecList.getCodecCount();
|
|
||||||
for (int i = 0; i < numCodecs; i++) {
|
|
||||||
MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
|
|
||||||
if (!codecInfo.isEncoder()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String[] types = codecInfo.getSupportedTypes();
|
|
||||||
for (String type : types) {
|
|
||||||
if (type.equalsIgnoreCase(mimeType)) {
|
|
||||||
return codecInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isRecognizedFormat(int colorFormat) {
|
|
||||||
switch (colorFormat) {
|
|
||||||
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
|
|
||||||
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
|
|
||||||
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
|
|
||||||
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
|
|
||||||
case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int selectColorFormat(MediaCodecInfo codecInfo, String mimeType) {
|
|
||||||
MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
|
|
||||||
for (int i = 0; i < capabilities.colorFormats.length; i++) {
|
|
||||||
int colorFormat = capabilities.colorFormats[i];
|
|
||||||
if (isRecognizedFormat(colorFormat)) {
|
|
||||||
return colorFormat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private long readAndWriteTrack(MediaExtractor extractor, MP4Builder mediaMuxer, MediaCodec.BufferInfo info, long start, long end, File file, boolean isAudio) throws Exception {
|
|
||||||
int trackIndex = selectTrack(extractor, isAudio);
|
|
||||||
if (trackIndex >= 0) {
|
|
||||||
extractor.selectTrack(trackIndex);
|
|
||||||
MediaFormat trackFormat = extractor.getTrackFormat(trackIndex);
|
|
||||||
int muxerTrackIndex = mediaMuxer.addTrack(trackFormat, isAudio);
|
|
||||||
int maxBufferSize = trackFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
|
|
||||||
boolean inputDone = false;
|
|
||||||
if (start > 0) {
|
|
||||||
extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
|
|
||||||
} else {
|
|
||||||
extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
|
|
||||||
}
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize);
|
|
||||||
long startTime = -1;
|
|
||||||
|
|
||||||
while (!inputDone) {
|
|
||||||
boolean eof = false;
|
|
||||||
int index = extractor.getSampleTrackIndex();
|
|
||||||
if (index == trackIndex) {
|
|
||||||
info.size = extractor.readSampleData(buffer, 0);
|
|
||||||
|
|
||||||
if (info.size < 0) {
|
|
||||||
info.size = 0;
|
|
||||||
eof = true;
|
|
||||||
} else {
|
|
||||||
info.presentationTimeUs = extractor.getSampleTime();
|
|
||||||
if (start > 0 && startTime == -1) {
|
|
||||||
startTime = info.presentationTimeUs;
|
|
||||||
}
|
|
||||||
if (end < 0 || info.presentationTimeUs < end) {
|
|
||||||
info.offset = 0;
|
|
||||||
info.flags = extractor.getSampleFlags();
|
|
||||||
if (!isAudio) {
|
|
||||||
buffer.limit(info.offset + info.size);
|
|
||||||
buffer.position(info.offset);
|
|
||||||
buffer.putInt(info.size - 4);
|
|
||||||
}
|
|
||||||
if (mediaMuxer.writeSampleData(muxerTrackIndex, buffer, info)) {
|
|
||||||
didWriteData(file.toString(), 0);
|
|
||||||
}
|
|
||||||
extractor.advance();
|
|
||||||
} else {
|
|
||||||
eof = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (index == -1) {
|
|
||||||
eof = true;
|
|
||||||
}
|
|
||||||
if (eof) {
|
|
||||||
inputDone = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extractor.unselectTrack(trackIndex);
|
|
||||||
return startTime;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean processOpenVideo() {
|
private boolean processOpenVideo() {
|
||||||
try {
|
try {
|
||||||
IsoFile isoFile = new IsoFile(videoPath);
|
IsoFile isoFile = new IsoFile(videoPath);
|
||||||
|
@ -767,7 +602,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
for (long size : sampleSizeBox.getSampleSizes()) {
|
for (long size : sampleSizeBox.getSampleSizes()) {
|
||||||
sampleSizes += size;
|
sampleSizes += size;
|
||||||
}
|
}
|
||||||
videoDuration = mediaHeaderBox.getDuration() / mediaHeaderBox.getTimescale();
|
videoDuration = (float)mediaHeaderBox.getDuration() / (float)mediaHeaderBox.getTimescale();
|
||||||
trackBitrate = (int)(sampleSizes * 8 / videoDuration);
|
trackBitrate = (int)(sampleSizes * 8 / videoDuration);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FileLog.e("tmessages", e);
|
FileLog.e("tmessages", e);
|
||||||
|
@ -826,444 +661,4 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||||
size += size / (32 * 1024) * 16;
|
size += size / (32 * 1024) * 16;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean startConvert2() {
|
|
||||||
File inputFile = new File(videoPath);
|
|
||||||
if (!inputFile.canRead()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
firstWrite = true;
|
|
||||||
File cacheFile = null;
|
|
||||||
boolean error = false;
|
|
||||||
long videoStartTime = startTime;
|
|
||||||
|
|
||||||
long time = System.currentTimeMillis();
|
|
||||||
|
|
||||||
if (resultWidth != 0 && resultHeight != 0) {
|
|
||||||
MP4Builder mediaMuxer = null;
|
|
||||||
MediaExtractor extractor = null;
|
|
||||||
|
|
||||||
MediaCodec decoder = null;
|
|
||||||
MediaCodec encoder = null;
|
|
||||||
InputSurface inputSurface = null;
|
|
||||||
OutputSurface outputSurface = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4";
|
|
||||||
UserConfig.lastLocalId--;
|
|
||||||
cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
|
|
||||||
UserConfig.saveConfig(false);
|
|
||||||
|
|
||||||
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
|
|
||||||
Mp4Movie movie = new Mp4Movie();
|
|
||||||
movie.setCacheFile(cacheFile);
|
|
||||||
movie.setRotation(rotationValue);
|
|
||||||
movie.setSize(resultWidth, resultHeight);
|
|
||||||
mediaMuxer = new MP4Builder().createMovie(movie);
|
|
||||||
extractor = new MediaExtractor();
|
|
||||||
extractor.setDataSource(inputFile.toString());
|
|
||||||
|
|
||||||
if (resultWidth != originalWidth || resultHeight != originalHeight) {
|
|
||||||
int videoIndex = -5;
|
|
||||||
videoIndex = selectTrack(extractor, false);
|
|
||||||
if (videoIndex >= 0) {
|
|
||||||
boolean outputDone = false;
|
|
||||||
boolean inputDone = false;
|
|
||||||
boolean decoderDone = false;
|
|
||||||
int swapUV = 0;
|
|
||||||
int videoTrackIndex = -5;
|
|
||||||
long videoTime = -1;
|
|
||||||
|
|
||||||
int colorFormat = 0;
|
|
||||||
int processorType = PROCESSOR_TYPE_OTHER;
|
|
||||||
if (Build.VERSION.SDK_INT < 18) {
|
|
||||||
MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
|
|
||||||
colorFormat = selectColorFormat(codecInfo, MIME_TYPE);
|
|
||||||
if (codecInfo.getName().contains("OMX.qcom.")) {
|
|
||||||
processorType = PROCESSOR_TYPE_QCOM;
|
|
||||||
if (Build.VERSION.SDK_INT == 16) { //nokia, lge
|
|
||||||
swapUV = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FileLog.e("tmessages", "codec = " + codecInfo.getName());
|
|
||||||
} else {
|
|
||||||
colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
|
|
||||||
}
|
|
||||||
FileLog.e("tmessages", "colorFormat = " + colorFormat);
|
|
||||||
|
|
||||||
int resultHeightAligned = resultHeight;
|
|
||||||
int padding = 0;
|
|
||||||
int bufferSize = resultWidth * resultHeight * 3 / 2;
|
|
||||||
if (processorType == PROCESSOR_TYPE_OTHER) {
|
|
||||||
if (resultHeight % 16 != 0) {
|
|
||||||
resultHeightAligned += (16 - (resultHeight % 16));
|
|
||||||
padding = resultWidth * (resultHeightAligned - resultHeight);
|
|
||||||
bufferSize += padding * 5 / 4;
|
|
||||||
}
|
|
||||||
} else if (processorType == PROCESSOR_TYPE_QCOM) {
|
|
||||||
if (!Build.MANUFACTURER.toLowerCase().equals("lge")) {
|
|
||||||
int uvoffset = (resultWidth * resultHeight + 2047) & ~2047;
|
|
||||||
padding = uvoffset - (resultWidth * resultHeight);
|
|
||||||
bufferSize += padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extractor.selectTrack(videoIndex);
|
|
||||||
if (startTime > 0) {
|
|
||||||
extractor.seekTo(startTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
|
|
||||||
} else {
|
|
||||||
extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
|
|
||||||
}
|
|
||||||
MediaFormat inputFormat = extractor.getTrackFormat(videoIndex);
|
|
||||||
|
|
||||||
MediaFormat outputFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight);
|
|
||||||
outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
|
|
||||||
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate != 0 ? bitrate : 921600);
|
|
||||||
outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 25);
|
|
||||||
outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
|
|
||||||
if (Build.VERSION.SDK_INT < 18) {
|
|
||||||
outputFormat.setInteger("stride", resultWidth);
|
|
||||||
outputFormat.setInteger("slice-height", resultHeightAligned);
|
|
||||||
}
|
|
||||||
|
|
||||||
encoder = MediaCodec.createEncoderByType(MIME_TYPE);
|
|
||||||
encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
|
|
||||||
if (Build.VERSION.SDK_INT >= 18) {
|
|
||||||
inputSurface = new InputSurface(encoder.createInputSurface());
|
|
||||||
inputSurface.makeCurrent();
|
|
||||||
}
|
|
||||||
encoder.start();
|
|
||||||
|
|
||||||
decoder = MediaCodec.createDecoderByType(inputFormat.getString(MediaFormat.KEY_MIME));
|
|
||||||
if (Build.VERSION.SDK_INT >= 18) {
|
|
||||||
outputSurface = new OutputSurface();
|
|
||||||
} else {
|
|
||||||
outputSurface = new OutputSurface(resultWidth, resultHeight);
|
|
||||||
}
|
|
||||||
decoder.configure(inputFormat, outputSurface.getSurface(), null, 0);
|
|
||||||
decoder.start();
|
|
||||||
|
|
||||||
final int TIMEOUT_USEC = 2500;
|
|
||||||
ByteBuffer[] decoderInputBuffers = decoder.getInputBuffers();
|
|
||||||
ByteBuffer[] encoderOutputBuffers = encoder.getOutputBuffers();
|
|
||||||
ByteBuffer[] encoderInputBuffers = null;
|
|
||||||
if (Build.VERSION.SDK_INT < 18) {
|
|
||||||
encoderInputBuffers = encoder.getInputBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!outputDone) {
|
|
||||||
if (!inputDone) {
|
|
||||||
boolean eof = false;
|
|
||||||
int index = extractor.getSampleTrackIndex();
|
|
||||||
if (index == videoIndex) {
|
|
||||||
int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
|
|
||||||
if (inputBufIndex >= 0) {
|
|
||||||
ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
|
|
||||||
int chunkSize = extractor.readSampleData(inputBuf, 0);
|
|
||||||
if (chunkSize < 0) {
|
|
||||||
decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
|
||||||
inputDone = true;
|
|
||||||
} else {
|
|
||||||
decoder.queueInputBuffer(inputBufIndex, 0, chunkSize, extractor.getSampleTime(), 0);
|
|
||||||
extractor.advance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (index == -1) {
|
|
||||||
eof = true;
|
|
||||||
}
|
|
||||||
if (eof) {
|
|
||||||
int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
|
|
||||||
if (inputBufIndex >= 0) {
|
|
||||||
decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
|
||||||
inputDone = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean decoderOutputAvailable = !decoderDone;
|
|
||||||
boolean encoderOutputAvailable = true;
|
|
||||||
while (decoderOutputAvailable || encoderOutputAvailable) {
|
|
||||||
int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
|
|
||||||
if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
|
|
||||||
encoderOutputAvailable = false;
|
|
||||||
} else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
|
|
||||||
encoderOutputBuffers = encoder.getOutputBuffers();
|
|
||||||
} else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
|
|
||||||
MediaFormat newFormat = encoder.getOutputFormat();
|
|
||||||
if (videoTrackIndex == -5) {
|
|
||||||
videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
|
|
||||||
}
|
|
||||||
} else if (encoderStatus < 0) {
|
|
||||||
throw new RuntimeException("unexpected result from encoder.dequeueOutputBuffer: " + encoderStatus);
|
|
||||||
} else {
|
|
||||||
ByteBuffer encodedData = encoderOutputBuffers[encoderStatus];
|
|
||||||
if (encodedData == null) {
|
|
||||||
throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null");
|
|
||||||
}
|
|
||||||
if (info.size > 1) {
|
|
||||||
if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
|
|
||||||
encodedData.limit(info.offset + info.size);
|
|
||||||
encodedData.position(info.offset);
|
|
||||||
encodedData.putInt(Integer.reverseBytes(info.size - 4));
|
|
||||||
if (mediaMuxer.writeSampleData(videoTrackIndex, encodedData, info)) {
|
|
||||||
didWriteData(cacheFile.toString(), 0);
|
|
||||||
}
|
|
||||||
} else if (videoTrackIndex == -5) {
|
|
||||||
byte[] csd = new byte[info.size];
|
|
||||||
encodedData.limit(info.offset + info.size);
|
|
||||||
encodedData.position(info.offset);
|
|
||||||
encodedData.get(csd);
|
|
||||||
ByteBuffer sps = null;
|
|
||||||
ByteBuffer pps = null;
|
|
||||||
for (int a = info.size - 1; a >= 0; a--) {
|
|
||||||
if (a > 3) {
|
|
||||||
if (csd[a] == 1 && csd[a - 1] == 0 && csd[a - 2] == 0 && csd[a - 3] == 0) {
|
|
||||||
sps = ByteBuffer.allocate(a - 3);
|
|
||||||
pps = ByteBuffer.allocate(info.size - (a - 3));
|
|
||||||
sps.put(csd, 0, a - 3).position(0);
|
|
||||||
pps.put(csd, a - 3, info.size - (a - 3)).position(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MediaFormat newFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight);
|
|
||||||
if (sps != null && pps != null) {
|
|
||||||
newFormat.setByteBuffer("csd-0", sps);
|
|
||||||
newFormat.setByteBuffer("csd-1", pps);
|
|
||||||
}
|
|
||||||
videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outputDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
|
|
||||||
encoder.releaseOutputBuffer(encoderStatus, false);
|
|
||||||
}
|
|
||||||
if (encoderStatus != MediaCodec.INFO_TRY_AGAIN_LATER) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!decoderDone) {
|
|
||||||
int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
|
|
||||||
if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
|
|
||||||
decoderOutputAvailable = false;
|
|
||||||
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
|
|
||||||
|
|
||||||
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
|
|
||||||
MediaFormat newFormat = decoder.getOutputFormat();
|
|
||||||
} else if (decoderStatus < 0) {
|
|
||||||
throw new RuntimeException("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
|
|
||||||
} else {
|
|
||||||
boolean doRender = false;
|
|
||||||
if (Build.VERSION.SDK_INT >= 18) {
|
|
||||||
doRender = info.size != 0;
|
|
||||||
} else {
|
|
||||||
doRender = info.size != 0 || info.presentationTimeUs != 0;
|
|
||||||
}
|
|
||||||
if (endTime > 0 && info.presentationTimeUs >= endTime) {
|
|
||||||
inputDone = true;
|
|
||||||
decoderDone = true;
|
|
||||||
doRender = false;
|
|
||||||
info.flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
|
|
||||||
}
|
|
||||||
if (startTime > 0 && videoTime == -1) {
|
|
||||||
if (info.presentationTimeUs < startTime) {
|
|
||||||
doRender = false;
|
|
||||||
FileLog.e("tmessages", "drop frame startTime = " + startTime + " present time = " + info.presentationTimeUs);
|
|
||||||
} else {
|
|
||||||
videoTime = info.presentationTimeUs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
decoder.releaseOutputBuffer(decoderStatus, doRender);
|
|
||||||
if (doRender) {
|
|
||||||
boolean errorWait = false;
|
|
||||||
try {
|
|
||||||
outputSurface.awaitNewImage();
|
|
||||||
} catch (Exception e) {
|
|
||||||
errorWait = true;
|
|
||||||
FileLog.e("tmessages", e);
|
|
||||||
}
|
|
||||||
if (!errorWait) {
|
|
||||||
if (Build.VERSION.SDK_INT >= 18) {
|
|
||||||
outputSurface.drawImage(false);
|
|
||||||
inputSurface.setPresentationTime(info.presentationTimeUs * 1000);
|
|
||||||
inputSurface.swapBuffers();
|
|
||||||
} else {
|
|
||||||
int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
|
|
||||||
if (inputBufIndex >= 0) {
|
|
||||||
outputSurface.drawImage(true);
|
|
||||||
ByteBuffer rgbBuf = outputSurface.getFrame();
|
|
||||||
ByteBuffer yuvBuf = encoderInputBuffers[inputBufIndex];
|
|
||||||
yuvBuf.clear();
|
|
||||||
Utilities.convertVideoFrame(rgbBuf, yuvBuf, colorFormat, resultWidth, resultHeight, padding, swapUV);
|
|
||||||
encoder.queueInputBuffer(inputBufIndex, 0, bufferSize, info.presentationTimeUs, 0);
|
|
||||||
} else {
|
|
||||||
FileLog.e("tmessages", "input buffer not available");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
|
|
||||||
decoderOutputAvailable = false;
|
|
||||||
FileLog.e("tmessages", "decoder stream end");
|
|
||||||
if (Build.VERSION.SDK_INT >= 18) {
|
|
||||||
encoder.signalEndOfInputStream();
|
|
||||||
} else {
|
|
||||||
int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
|
|
||||||
if (inputBufIndex >= 0) {
|
|
||||||
encoder.queueInputBuffer(inputBufIndex, 0, 1, info.presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extractor.unselectTrack(videoIndex);
|
|
||||||
if (videoTime != -1) {
|
|
||||||
videoStartTime = videoTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
long videoTime = readAndWriteTrack(extractor, mediaMuxer, info, startTime, endTime, cacheFile, false);
|
|
||||||
if (videoTime != -1) {
|
|
||||||
videoStartTime = videoTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
readAndWriteTrack(extractor, mediaMuxer, info, videoStartTime, endTime, cacheFile, true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
error = true;
|
|
||||||
FileLog.e("tmessages", e);
|
|
||||||
} finally {
|
|
||||||
if (extractor != null) {
|
|
||||||
extractor.release();
|
|
||||||
extractor = null;
|
|
||||||
}
|
|
||||||
if (outputSurface != null) {
|
|
||||||
outputSurface.release();
|
|
||||||
outputSurface = null;
|
|
||||||
}
|
|
||||||
if (inputSurface != null) {
|
|
||||||
inputSurface.release();
|
|
||||||
inputSurface = null;
|
|
||||||
}
|
|
||||||
if (decoder != null) {
|
|
||||||
decoder.stop();
|
|
||||||
decoder.release();
|
|
||||||
decoder = null;
|
|
||||||
}
|
|
||||||
if (encoder != null) {
|
|
||||||
encoder.stop();
|
|
||||||
encoder.release();
|
|
||||||
encoder = null;
|
|
||||||
}
|
|
||||||
if (mediaMuxer != null) {
|
|
||||||
try {
|
|
||||||
mediaMuxer.finishMovie(false);
|
|
||||||
} catch (Exception e) {
|
|
||||||
FileLog.e("tmessages", e);
|
|
||||||
}
|
|
||||||
mediaMuxer = null;
|
|
||||||
}
|
|
||||||
FileLog.e("tmessages", "time = " + (System.currentTimeMillis() - time));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!error && cacheFile != null) {
|
|
||||||
didWriteData(cacheFile.toString(), cacheFile.length());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startConvert() throws Exception {
|
|
||||||
IsoFile isoFile = new IsoFile(videoPath);
|
|
||||||
TrackBox trackBox = (TrackBox) Path.getPath(isoFile, "/moov/trak/mdia/minf/stbl/stsd/avc1/../../../../../");
|
|
||||||
AvcConfigurationBox avcConfigurationBox = (AvcConfigurationBox) Path.getPath(trackBox, "mdia/minf/stbl/stsd/avc1/avcC");
|
|
||||||
avcConfigurationBox.parseDetails();
|
|
||||||
|
|
||||||
Movie movie = MovieCreator.build(videoPath);
|
|
||||||
|
|
||||||
List<Track> tracks = movie.getTracks();
|
|
||||||
movie.setTracks(new LinkedList<Track>());
|
|
||||||
|
|
||||||
double startTime = 0;
|
|
||||||
double endTime = 0;
|
|
||||||
|
|
||||||
for (Track track : tracks) {
|
|
||||||
if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
|
|
||||||
double duration = (double) track.getDuration() / (double) track.getTrackMetaData().getTimescale();
|
|
||||||
startTime = correctTimeToSyncSample(track, videoTimelineView.getLeftProgress() * duration, false);
|
|
||||||
endTime = videoTimelineView.getRightProgress() * duration;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Track track : tracks) {
|
|
||||||
long currentSample = 0;
|
|
||||||
double currentTime = 0;
|
|
||||||
double lastTime = 0;
|
|
||||||
long startSample = 0;
|
|
||||||
long endSample = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < track.getSampleDurations().length; i++) {
|
|
||||||
long delta = track.getSampleDurations()[i];
|
|
||||||
if (currentTime > lastTime && currentTime <= startTime) {
|
|
||||||
startSample = currentSample;
|
|
||||||
}
|
|
||||||
if (currentTime > lastTime && currentTime <= endTime) {
|
|
||||||
endSample = currentSample;
|
|
||||||
}
|
|
||||||
lastTime = currentTime;
|
|
||||||
currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale();
|
|
||||||
currentSample++;
|
|
||||||
}
|
|
||||||
movie.addTrack(new CroppedTrack(track, startSample, endSample));
|
|
||||||
}
|
|
||||||
Container out = new DefaultMp4Builder().build(movie);
|
|
||||||
|
|
||||||
String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4";
|
|
||||||
UserConfig.lastLocalId--;
|
|
||||||
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
|
|
||||||
UserConfig.saveConfig(false);
|
|
||||||
|
|
||||||
FileOutputStream fos = new FileOutputStream(cacheFile);
|
|
||||||
FileChannel fc = fos.getChannel();
|
|
||||||
out.writeContainer(fc);
|
|
||||||
|
|
||||||
fc.close();
|
|
||||||
fos.close();
|
|
||||||
if (delegate != null) {
|
|
||||||
//delegate.didFinishedVideoConverting(cacheFile.getAbsolutePath());
|
|
||||||
finishFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double correctTimeToSyncSample(Track track, double cutHere, boolean next) {
|
|
||||||
double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
|
|
||||||
long currentSample = 0;
|
|
||||||
double currentTime = 0;
|
|
||||||
for (int i = 0; i < track.getSampleDurations().length; i++) {
|
|
||||||
long delta = track.getSampleDurations()[i];
|
|
||||||
if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
|
|
||||||
timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime;
|
|
||||||
}
|
|
||||||
currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale();
|
|
||||||
currentSample++;
|
|
||||||
}
|
|
||||||
double previous = 0;
|
|
||||||
for (double timeOfSyncSample : timeOfSyncSamples) {
|
|
||||||
if (timeOfSyncSample > cutHere) {
|
|
||||||
if (next) {
|
|
||||||
return timeOfSyncSample;
|
|
||||||
} else {
|
|
||||||
return previous;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
previous = timeOfSyncSample;
|
|
||||||
}
|
|
||||||
return timeOfSyncSamples[timeOfSyncSamples.length - 1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import android.view.animation.AnimationUtils;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
import org.telegram.android.AndroidUtilities;
|
import org.telegram.android.AndroidUtilities;
|
||||||
|
import org.telegram.android.NotificationCenter;
|
||||||
import org.telegram.messenger.FileLog;
|
import org.telegram.messenger.FileLog;
|
||||||
import org.telegram.messenger.R;
|
import org.telegram.messenger.R;
|
||||||
|
|
||||||
|
@ -199,11 +200,11 @@ public class ActionBarLayout extends FrameLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSlideAnimationEnd(boolean backAnimation) {
|
private void onSlideAnimationEnd(boolean backAnimation) {
|
||||||
containerView.setX(0);
|
containerView.setTranslationX(0);
|
||||||
containerViewBack.setX(0);
|
containerViewBack.setTranslationX(0);
|
||||||
actionBar.stopMoving(backAnimation);
|
actionBar.stopMoving(backAnimation);
|
||||||
shadowView.setVisibility(View.INVISIBLE);
|
shadowView.setVisibility(View.INVISIBLE);
|
||||||
shadowView.setX(-AndroidUtilities.dp(2));
|
shadowView.setTranslationX(-AndroidUtilities.dp(2));
|
||||||
if (!backAnimation) {
|
if (!backAnimation) {
|
||||||
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
|
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
|
||||||
lastFragment.onPause();
|
lastFragment.onPause();
|
||||||
|
@ -240,7 +241,7 @@ public class ActionBarLayout extends FrameLayout {
|
||||||
startedTracking = true;
|
startedTracking = true;
|
||||||
startedTrackingX = (int) ev.getX();
|
startedTrackingX = (int) ev.getX();
|
||||||
shadowView.setVisibility(View.VISIBLE);
|
shadowView.setVisibility(View.VISIBLE);
|
||||||
shadowView.setX(-AndroidUtilities.dp(2));
|
shadowView.setTranslationX(-AndroidUtilities.dp(2));
|
||||||
containerViewBack.setVisibility(View.VISIBLE);
|
containerViewBack.setVisibility(View.VISIBLE);
|
||||||
beginTrackingSent = false;
|
beginTrackingSent = false;
|
||||||
|
|
||||||
|
@ -297,8 +298,8 @@ public class ActionBarLayout extends FrameLayout {
|
||||||
beginTrackingSent = true;
|
beginTrackingSent = true;
|
||||||
}
|
}
|
||||||
actionBar.moveActionBarByX(dx);
|
actionBar.moveActionBarByX(dx);
|
||||||
containerView.setX(dx);
|
containerView.setTranslationX(dx);
|
||||||
shadowView.setX(dx - AndroidUtilities.dp(2));
|
shadowView.setTranslationX(dx - AndroidUtilities.dp(2));
|
||||||
}
|
}
|
||||||
} else if (ev != null && ev.getPointerId(0) == startedTrackingPointerId && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_POINTER_UP)) {
|
} else if (ev != null && ev.getPointerId(0) == startedTrackingPointerId && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_POINTER_UP)) {
|
||||||
if (velocityTracker == null) {
|
if (velocityTracker == null) {
|
||||||
|
@ -488,19 +489,20 @@ public class ActionBarLayout extends FrameLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean presentFragment(BaseFragment fragment) {
|
public boolean presentFragment(BaseFragment fragment) {
|
||||||
return presentFragment(fragment, false, false);
|
return presentFragment(fragment, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean presentFragment(BaseFragment fragment, boolean removeLast) {
|
public boolean presentFragment(BaseFragment fragment, boolean removeLast) {
|
||||||
return presentFragment(fragment, removeLast, false);
|
return presentFragment(fragment, removeLast, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation) {
|
public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation, boolean check) {
|
||||||
if (checkTransitionAnimation() || delegate != null && !delegate.needPresentFragment(fragment, removeLast, forceWithoutAnimation, this) || !fragment.onFragmentCreate()) {
|
if (checkTransitionAnimation() || delegate != null && check && !delegate.needPresentFragment(fragment, removeLast, forceWithoutAnimation, this) || !fragment.onFragmentCreate()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (parentActivity.getCurrentFocus() != null) {
|
if (parentActivity.getCurrentFocus() != null) {
|
||||||
AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus());
|
AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus());
|
||||||
|
NotificationCenter.getInstance().postNotificationName(NotificationCenter.hideEmojiKeyboard);
|
||||||
}
|
}
|
||||||
boolean needAnimation = openAnimation != null && !forceWithoutAnimation && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true);
|
boolean needAnimation = openAnimation != null && !forceWithoutAnimation && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true);
|
||||||
if (useAlphaAnimations && fragmentsStack.size() == 0 && alphaOpenAnimation == null) {
|
if (useAlphaAnimations && fragmentsStack.size() == 0 && alphaOpenAnimation == null) {
|
||||||
|
@ -533,6 +535,9 @@ public class ActionBarLayout extends FrameLayout {
|
||||||
|
|
||||||
if (!needAnimation) {
|
if (!needAnimation) {
|
||||||
presentFragmentInternalRemoveOld(removeLast, currentFragment);
|
presentFragmentInternalRemoveOld(removeLast, currentFragment);
|
||||||
|
if (backgroundView != null) {
|
||||||
|
backgroundView.setVisibility(VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needAnimation) {
|
if (needAnimation) {
|
||||||
|
|
|
@ -157,11 +157,14 @@ public class BaseFragment {
|
||||||
if (parentLayout == null) {
|
if (parentLayout == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
parentLayout.presentFragment(fragment, removeLast, forceWithoutAnimation);
|
parentLayout.presentFragment(fragment, removeLast, forceWithoutAnimation, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Activity getParentActivity() {
|
public Activity getParentActivity() {
|
||||||
return parentLayout.parentActivity;
|
if (parentLayout != null) {
|
||||||
|
return parentLayout.parentActivity;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showActionBar() {
|
public void showActionBar() {
|
||||||
|
|
|
@ -45,6 +45,8 @@ import org.telegram.messenger.R;
|
||||||
import org.telegram.messenger.TLRPC;
|
import org.telegram.messenger.TLRPC;
|
||||||
import org.telegram.ui.ApplicationLoader;
|
import org.telegram.ui.ApplicationLoader;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
public class ChatActivityEnterView implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate {
|
public class ChatActivityEnterView implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate {
|
||||||
|
|
||||||
public static interface ChatActivityEnterViewDelegate {
|
public static interface ChatActivityEnterViewDelegate {
|
||||||
|
@ -87,6 +89,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen
|
||||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.closeChats);
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.closeChats);
|
||||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidSent);
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidSent);
|
||||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded);
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded);
|
||||||
|
NotificationCenter.getInstance().addObserver(this, NotificationCenter.hideEmojiKeyboard);
|
||||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
||||||
sendByEnter = preferences.getBoolean("send_by_enter", false);
|
sendByEnter = preferences.getBoolean("send_by_enter", false);
|
||||||
}
|
}
|
||||||
|
@ -99,6 +102,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen
|
||||||
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeChats);
|
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeChats);
|
||||||
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidSent);
|
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidSent);
|
||||||
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.emojiDidLoaded);
|
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.emojiDidLoaded);
|
||||||
|
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.hideEmojiKeyboard);
|
||||||
if (mWakeLock != null) {
|
if (mWakeLock != null) {
|
||||||
try {
|
try {
|
||||||
mWakeLock.release();
|
mWakeLock.release();
|
||||||
|
@ -507,6 +511,15 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emojiPopup = new PopupWindow(emojiView);
|
emojiPopup = new PopupWindow(emojiView);
|
||||||
|
|
||||||
|
/*Utry {
|
||||||
|
Method method = emojiPopup.getClass().getMethod("setWindowLayoutType", int.class);
|
||||||
|
if (method != null) {
|
||||||
|
method.invoke(emojiPopup, WindowManager.LayoutParams.LAST_SUB_WINDOW);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
//don't promt
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDelegate(ChatActivityEnterViewDelegate delegate) {
|
public void setDelegate(ChatActivityEnterViewDelegate delegate) {
|
||||||
|
@ -646,6 +659,8 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen
|
||||||
if (delegate != null) {
|
if (delegate != null) {
|
||||||
delegate.onMessageSend();
|
delegate.onMessageSend();
|
||||||
}
|
}
|
||||||
|
} else if (id == NotificationCenter.hideEmojiKeyboard) {
|
||||||
|
hideEmojiPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,30 +213,26 @@ public class EmojiView extends LinearLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return this.data.length;
|
return data.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getItem(int paramInt)
|
public Object getItem(int i) {
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getItemId(int paramInt)
|
public long getItemId(int i) {
|
||||||
{
|
return data[i];
|
||||||
return this.data[paramInt];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public View getView(int paramInt, View paramView, ViewGroup paramViewGroup) {
|
public View getView(int i, View view, ViewGroup paramViewGroup) {
|
||||||
ImageView localObject;
|
ImageView imageView = (ImageView)view;
|
||||||
if (paramView != null) {
|
if (imageView == null) {
|
||||||
localObject = (ImageView)paramView;
|
imageView = new ImageView(EmojiView.this.getContext()) {
|
||||||
} else {
|
|
||||||
localObject = new ImageView(EmojiView.this.getContext()) {
|
|
||||||
public void onMeasure(int paramAnonymousInt1, int paramAnonymousInt2) {
|
public void onMeasure(int paramAnonymousInt1, int paramAnonymousInt2) {
|
||||||
setMeasuredDimension(View.MeasureSpec.getSize(paramAnonymousInt1), View.MeasureSpec.getSize(paramAnonymousInt1));
|
setMeasuredDimension(View.MeasureSpec.getSize(paramAnonymousInt1), View.MeasureSpec.getSize(paramAnonymousInt1));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
localObject.setOnClickListener(new View.OnClickListener() {
|
imageView.setOnClickListener(new View.OnClickListener() {
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (EmojiView.this.listener != null) {
|
if (EmojiView.this.listener != null) {
|
||||||
EmojiView.this.listener.onEmojiSelected(EmojiView.this.convert((Long)view.getTag()));
|
EmojiView.this.listener.onEmojiSelected(EmojiView.this.convert((Long)view.getTag()));
|
||||||
|
@ -244,13 +240,12 @@ public class EmojiView extends LinearLayout {
|
||||||
EmojiView.this.addToRecent((Long)view.getTag());
|
EmojiView.this.addToRecent((Long)view.getTag());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
localObject.setBackgroundResource(R.drawable.list_selector);
|
imageView.setBackgroundResource(R.drawable.list_selector);
|
||||||
localObject.setScaleType(ImageView.ScaleType.CENTER);
|
imageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||||
}
|
}
|
||||||
|
imageView.setImageDrawable(Emoji.getEmojiBigDrawable(data[i]));
|
||||||
localObject.setImageDrawable(Emoji.getEmojiBigDrawable(this.data[paramInt]));
|
imageView.setTag(data[i]);
|
||||||
localObject.setTag(this.data[paramInt]);
|
return imageView;
|
||||||
return localObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,7 +12,6 @@ import java.util.Locale;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Paint.Style;
|
import android.graphics.Paint.Style;
|
||||||
|
@ -42,15 +41,7 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
||||||
public int getPageIconResId(int position);
|
public int getPageIconResId(int position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
private static final int[] ATTRS = new int[] {
|
|
||||||
android.R.attr.textSize,
|
|
||||||
android.R.attr.textColor
|
|
||||||
};
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
private LinearLayout.LayoutParams defaultTabLayoutParams;
|
private LinearLayout.LayoutParams defaultTabLayoutParams;
|
||||||
private LinearLayout.LayoutParams expandedTabLayoutParams;
|
|
||||||
|
|
||||||
private final PageListener pageListener = new PageListener();
|
private final PageListener pageListener = new PageListener();
|
||||||
public OnPageChangeListener delegatePageListener;
|
public OnPageChangeListener delegatePageListener;
|
||||||
|
@ -66,8 +57,6 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
||||||
private Paint rectPaint;
|
private Paint rectPaint;
|
||||||
private Paint dividerPaint;
|
private Paint dividerPaint;
|
||||||
|
|
||||||
private boolean checkedTabWidths = false;
|
|
||||||
|
|
||||||
private int indicatorColor = 0xFF666666;
|
private int indicatorColor = 0xFF666666;
|
||||||
private int underlineColor = 0x1A000000;
|
private int underlineColor = 0x1A000000;
|
||||||
private int dividerColor = 0x1A000000;
|
private int dividerColor = 0x1A000000;
|
||||||
|
@ -122,33 +111,6 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
||||||
dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
|
dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
|
||||||
tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
|
tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
|
||||||
|
|
||||||
// get system attrs (android:textSize and android:textColor)
|
|
||||||
|
|
||||||
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
|
|
||||||
|
|
||||||
tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
|
|
||||||
tabTextColor = a.getColor(1, tabTextColor);
|
|
||||||
|
|
||||||
a.recycle();
|
|
||||||
|
|
||||||
// get custom attrs
|
|
||||||
|
|
||||||
a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);
|
|
||||||
|
|
||||||
indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_indicatorColor, indicatorColor);
|
|
||||||
underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_underlineColor, underlineColor);
|
|
||||||
dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_dividerColor, dividerColor);
|
|
||||||
indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_indicatorHeight, indicatorHeight);
|
|
||||||
underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_underlineHeight, underlineHeight);
|
|
||||||
dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_dividerPadding1, dividerPadding);
|
|
||||||
tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_tabPaddingLeftRight, tabPadding);
|
|
||||||
tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_tabBackground, tabBackgroundResId);
|
|
||||||
shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_shouldExpand, shouldExpand);
|
|
||||||
scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_scrollOffset, scrollOffset);
|
|
||||||
textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_textAllCaps1, textAllCaps);
|
|
||||||
|
|
||||||
a.recycle();
|
|
||||||
|
|
||||||
rectPaint = new Paint();
|
rectPaint = new Paint();
|
||||||
rectPaint.setAntiAlias(true);
|
rectPaint.setAntiAlias(true);
|
||||||
rectPaint.setStyle(Style.FILL);
|
rectPaint.setStyle(Style.FILL);
|
||||||
|
@ -158,7 +120,6 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
||||||
dividerPaint.setStrokeWidth(dividerWidth);
|
dividerPaint.setStrokeWidth(dividerWidth);
|
||||||
|
|
||||||
defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
||||||
expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);
|
|
||||||
|
|
||||||
if (locale == null) {
|
if (locale == null) {
|
||||||
locale = getResources().getConfiguration().locale;
|
locale = getResources().getConfiguration().locale;
|
||||||
|
@ -199,8 +160,6 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
||||||
|
|
||||||
updateTabStyles();
|
updateTabStyles();
|
||||||
|
|
||||||
checkedTabWidths = false;
|
|
||||||
|
|
||||||
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
|
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
@ -296,7 +255,6 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -312,7 +270,6 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scrollToChild(int position, int offset) {
|
private void scrollToChild(int position, int offset) {
|
||||||
|
|
||||||
if (tabCount == 0) {
|
if (tabCount == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -327,7 +284,6 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
||||||
lastScrollX = newScrollX;
|
lastScrollX = newScrollX;
|
||||||
scrollTo(newScrollX, 0);
|
scrollTo(newScrollX, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -615,5 +571,4 @@ public class PagerSlidingTabStrip extends HorizontalScrollView {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
TMessagesProj/src/main/res/drawable-hdpi/doccancel_b.png
Normal file
After Width: | Height: | Size: 483 B |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 490 B |
BIN
TMessagesProj/src/main/res/drawable-hdpi/docload_b.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.5 KiB |
BIN
TMessagesProj/src/main/res/drawable-hdpi/docload_g.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.5 KiB |
BIN
TMessagesProj/src/main/res/drawable-hdpi/docpause_b.png
Normal file
After Width: | Height: | Size: 260 B |
BIN
TMessagesProj/src/main/res/drawable-hdpi/docpause_g.png
Normal file
After Width: | Height: | Size: 268 B |
BIN
TMessagesProj/src/main/res/drawable-hdpi/photocancel.png
Executable file → Normal file
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
TMessagesProj/src/main/res/drawable-hdpi/photogif.png
Executable file → Normal file
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
TMessagesProj/src/main/res/drawable-hdpi/photoload.png
Executable file → Normal file
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
TMessagesProj/src/main/res/drawable-hdpi/photopause.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 599 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 613 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 965 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 964 B |
BIN
TMessagesProj/src/main/res/drawable-ldpi/docpause_b.png
Normal file
After Width: | Height: | Size: 196 B |
BIN
TMessagesProj/src/main/res/drawable-ldpi/docpause_g.png
Normal file
After Width: | Height: | Size: 203 B |
BIN
TMessagesProj/src/main/res/drawable-ldpi/photocancel.png
Executable file → Normal file
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 724 B |
BIN
TMessagesProj/src/main/res/drawable-ldpi/photogif.png
Executable file → Normal file
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 853 B |
BIN
TMessagesProj/src/main/res/drawable-ldpi/photoload.png
Executable file → Normal file
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 708 B |
BIN
TMessagesProj/src/main/res/drawable-ldpi/photopause.png
Normal file
After Width: | Height: | Size: 578 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 795 B |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 786 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 803 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 410 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 406 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
TMessagesProj/src/main/res/drawable-mdpi/docpause_b.png
Normal file
After Width: | Height: | Size: 212 B |
BIN
TMessagesProj/src/main/res/drawable-mdpi/docpause_g.png
Normal file
After Width: | Height: | Size: 223 B |
BIN
TMessagesProj/src/main/res/drawable-mdpi/photocancel.png
Executable file → Normal file
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1 KiB |
BIN
TMessagesProj/src/main/res/drawable-mdpi/photogif.png
Executable file → Normal file
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
TMessagesProj/src/main/res/drawable-mdpi/photoload.png
Executable file → Normal file
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 899 B |
BIN
TMessagesProj/src/main/res/drawable-mdpi/photopause.png
Normal file
After Width: | Height: | Size: 781 B |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 674 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 670 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.5 KiB |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/docpause_b.png
Normal file
After Width: | Height: | Size: 298 B |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/docpause_g.png
Normal file
After Width: | Height: | Size: 315 B |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/photocancel.png
Executable file → Normal file
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2 KiB |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/photogif.png
Executable file → Normal file
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.2 KiB |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/photoload.png
Executable file → Normal file
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/photopause.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 831 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 831 B |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.7 KiB |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/docpause_b.png
Normal file
After Width: | Height: | Size: 415 B |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/docpause_g.png
Normal file
After Width: | Height: | Size: 406 B |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/photocancel.png
Executable file → Normal file
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 2.8 KiB |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/photogif.png
Executable file → Normal file
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/photoload.png
Executable file → Normal file
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.5 KiB |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/photopause.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.2 KiB |
|
@ -317,6 +317,7 @@
|
||||||
<string name="EditVideo">تحرير الفيديو</string>
|
<string name="EditVideo">تحرير الفيديو</string>
|
||||||
<string name="OriginalVideo">الفيديو الأصلي</string>
|
<string name="OriginalVideo">الفيديو الأصلي</string>
|
||||||
<string name="EditedVideo">تم تحرير الفيديو</string>
|
<string name="EditedVideo">تم تحرير الفيديو</string>
|
||||||
|
<string name="SendingVideo">Sending video...</string>
|
||||||
|
|
||||||
<!--button titles-->
|
<!--button titles-->
|
||||||
<string name="Next">التالي</string>
|
<string name="Next">التالي</string>
|
||||||
|
|
|
@ -317,6 +317,7 @@
|
||||||
<string name="EditVideo">Video bearbeiten</string>
|
<string name="EditVideo">Video bearbeiten</string>
|
||||||
<string name="OriginalVideo">Originalvideo</string>
|
<string name="OriginalVideo">Originalvideo</string>
|
||||||
<string name="EditedVideo">Bearbeitetes Video</string>
|
<string name="EditedVideo">Bearbeitetes Video</string>
|
||||||
|
<string name="SendingVideo">Sending video...</string>
|
||||||
|
|
||||||
<!--button titles-->
|
<!--button titles-->
|
||||||
<string name="Next">Weiter</string>
|
<string name="Next">Weiter</string>
|
||||||
|
|
|
@ -317,6 +317,7 @@
|
||||||
<string name="EditVideo">Editar vídeo</string>
|
<string name="EditVideo">Editar vídeo</string>
|
||||||
<string name="OriginalVideo">Vídeo original</string>
|
<string name="OriginalVideo">Vídeo original</string>
|
||||||
<string name="EditedVideo">Vídeo editado</string>
|
<string name="EditedVideo">Vídeo editado</string>
|
||||||
|
<string name="SendingVideo">Sending video...</string>
|
||||||
|
|
||||||
<!--button titles-->
|
<!--button titles-->
|
||||||
<string name="Next">Siguiente</string>
|
<string name="Next">Siguiente</string>
|
||||||
|
|
|
@ -317,6 +317,7 @@
|
||||||
<string name="EditVideo">Modifica video</string>
|
<string name="EditVideo">Modifica video</string>
|
||||||
<string name="OriginalVideo">Video originale</string>
|
<string name="OriginalVideo">Video originale</string>
|
||||||
<string name="EditedVideo">Video modificato</string>
|
<string name="EditedVideo">Video modificato</string>
|
||||||
|
<string name="SendingVideo">Sending video...</string>
|
||||||
|
|
||||||
<!--button titles-->
|
<!--button titles-->
|
||||||
<string name="Next">Avanti</string>
|
<string name="Next">Avanti</string>
|
||||||
|
|
|
@ -317,6 +317,7 @@
|
||||||
<string name="EditVideo">Video bewerken</string>
|
<string name="EditVideo">Video bewerken</string>
|
||||||
<string name="OriginalVideo">Originele video</string>
|
<string name="OriginalVideo">Originele video</string>
|
||||||
<string name="EditedVideo">Bewerkte video</string>
|
<string name="EditedVideo">Bewerkte video</string>
|
||||||
|
<string name="SendingVideo">Sending video...</string>
|
||||||
|
|
||||||
<!--button titles-->
|
<!--button titles-->
|
||||||
<string name="Next">Volgende</string>
|
<string name="Next">Volgende</string>
|
||||||
|
|
|
@ -317,6 +317,7 @@
|
||||||
<string name="EditVideo">Editar Vídeo</string>
|
<string name="EditVideo">Editar Vídeo</string>
|
||||||
<string name="OriginalVideo">Vídeo Original</string>
|
<string name="OriginalVideo">Vídeo Original</string>
|
||||||
<string name="EditedVideo">Vídeo Editado</string>
|
<string name="EditedVideo">Vídeo Editado</string>
|
||||||
|
<string name="SendingVideo">Sending video...</string>
|
||||||
|
|
||||||
<!--button titles-->
|
<!--button titles-->
|
||||||
<string name="Next">Próximo</string>
|
<string name="Next">Próximo</string>
|
||||||
|
|
|
@ -317,6 +317,7 @@
|
||||||
<string name="EditVideo">Edit Video</string>
|
<string name="EditVideo">Edit Video</string>
|
||||||
<string name="OriginalVideo">Original Video</string>
|
<string name="OriginalVideo">Original Video</string>
|
||||||
<string name="EditedVideo">Edited Video</string>
|
<string name="EditedVideo">Edited Video</string>
|
||||||
|
<string name="SendingVideo">Sending video...</string>
|
||||||
|
|
||||||
<!--button titles-->
|
<!--button titles-->
|
||||||
<string name="Next">Seguinte</string>
|
<string name="Next">Seguinte</string>
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
|
|
||||||
<declare-styleable name="PagerSlidingTabStrip">
|
|
||||||
<attr name="indicatorColor" format="color" />
|
|
||||||
<attr name="underlineColor" format="color" />
|
|
||||||
<attr name="dividerColor" format="color" />
|
|
||||||
<attr name="indicatorHeight" format="dimension" />
|
|
||||||
<attr name="underlineHeight" format="dimension" />
|
|
||||||
<attr name="dividerPadding1" format="dimension" />
|
|
||||||
<attr name="tabPaddingLeftRight" format="dimension" />
|
|
||||||
<attr name="scrollOffset" format="dimension" />
|
|
||||||
<attr name="tabBackground" format="reference" />
|
|
||||||
<attr name="shouldExpand" format="boolean" />
|
|
||||||
<attr name="textAllCaps1" format="boolean" />
|
|
||||||
</declare-styleable>
|
|
||||||
|
|
||||||
</resources>
|
|