NewPipe-app-android/app/src/main/java/us/shandian/giga/util/Utility.java

291 lines
8.8 KiB
Java

package us.shandian.giga.util;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.google.android.exoplayer2.util.Util;
import org.schabi.newpipe.R;
import org.schabi.newpipe.streams.io.SharpInputStream;
import org.schabi.newpipe.streams.io.StoredFileHelper;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.util.Locale;
import okio.ByteString;
public class Utility {
public enum FileType {
VIDEO,
MUSIC,
SUBTITLE,
UNKNOWN
}
/**
* Get amount of free system's memory.
* @return free memory (bytes)
*/
public static long getSystemFreeMemory() {
try {
final StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
return statFs.getAvailableBlocksLong() * statFs.getBlockSizeLong();
} catch (final Exception e) {
// do nothing
}
return -1;
}
public static String formatBytes(long bytes) {
Locale locale = Locale.getDefault();
if (bytes < 1024) {
return String.format(locale, "%d B", bytes);
} else if (bytes < 1024 * 1024) {
return String.format(locale, "%.2f kB", bytes / 1024d);
} else if (bytes < 1024 * 1024 * 1024) {
return String.format(locale, "%.2f MB", bytes / 1024d / 1024d);
} else {
return String.format(locale, "%.2f GB", bytes / 1024d / 1024d / 1024d);
}
}
public static String formatSpeed(double speed) {
Locale locale = Locale.getDefault();
if (speed < 1024) {
return String.format(locale, "%.2f B/s", speed);
} else if (speed < 1024 * 1024) {
return String.format(locale, "%.2f kB/s", speed / 1024);
} else if (speed < 1024 * 1024 * 1024) {
return String.format(locale, "%.2f MB/s", speed / 1024 / 1024);
} else {
return String.format(locale, "%.2f GB/s", speed / 1024 / 1024 / 1024);
}
}
public static void writeToFile(@NonNull File file, @NonNull Serializable serializable) {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
objectOutputStream.writeObject(serializable);
} catch (Exception e) {
//nothing to do
}
//nothing to do
}
@Nullable
@SuppressWarnings("unchecked")
public static <T> T readFromFile(File file) {
T object;
try (ObjectInputStream objectInputStream =
new ObjectInputStream(new FileInputStream(file))) {
object = (T) objectInputStream.readObject();
} catch (Exception e) {
Log.e("Utility", "Failed to deserialize the object", e);
object = null;
}
return object;
}
@Nullable
public static String getFileExt(String url) {
int index;
if ((index = url.indexOf("?")) > -1) {
url = url.substring(0, index);
}
index = url.lastIndexOf(".");
if (index == -1) {
return null;
} else {
String ext = url.substring(index);
if ((index = ext.indexOf("%")) > -1) {
ext = ext.substring(0, index);
}
if ((index = ext.indexOf("/")) > -1) {
ext = ext.substring(0, index);
}
return ext.toLowerCase();
}
}
public static FileType getFileType(char kind, String file) {
switch (kind) {
case 'v':
return FileType.VIDEO;
case 'a':
return FileType.MUSIC;
case 's':
return FileType.SUBTITLE;
//default '?':
}
if (file.endsWith(".srt") || file.endsWith(".vtt") || file.endsWith(".ssa")) {
return FileType.SUBTITLE;
} else if (file.endsWith(".mp3") || file.endsWith(".wav") || file.endsWith(".flac") || file.endsWith(".m4a") || file.endsWith(".opus")) {
return FileType.MUSIC;
} else if (file.endsWith(".mp4") || file.endsWith(".mpeg") || file.endsWith(".rm") || file.endsWith(".rmvb")
|| file.endsWith(".flv") || file.endsWith(".webp") || file.endsWith(".webm")) {
return FileType.VIDEO;
}
return FileType.UNKNOWN;
}
@ColorInt
public static int getBackgroundForFileType(Context ctx, FileType type) {
int colorRes;
switch (type) {
case MUSIC:
colorRes = R.color.audio_left_to_load_color;
break;
case VIDEO:
colorRes = R.color.video_left_to_load_color;
break;
case SUBTITLE:
colorRes = R.color.subtitle_left_to_load_color;
break;
default:
colorRes = R.color.gray;
}
return ContextCompat.getColor(ctx, colorRes);
}
@ColorInt
public static int getForegroundForFileType(Context ctx, FileType type) {
int colorRes;
switch (type) {
case MUSIC:
colorRes = R.color.audio_already_load_color;
break;
case VIDEO:
colorRes = R.color.video_already_load_color;
break;
case SUBTITLE:
colorRes = R.color.subtitle_already_load_color;
break;
default:
colorRes = R.color.gray;
break;
}
return ContextCompat.getColor(ctx, colorRes);
}
@DrawableRes
public static int getIconForFileType(FileType type) {
switch (type) {
case MUSIC:
return R.drawable.ic_headset;
default:
case VIDEO:
return R.drawable.ic_movie;
case SUBTITLE:
return R.drawable.ic_subtitles;
}
}
public static String checksum(final StoredFileHelper source, final int algorithmId)
throws IOException {
ByteString byteString;
try (var inputStream = new SharpInputStream(source.getStream())) {
byteString = ByteString.of(Util.toByteArray(inputStream));
}
if (algorithmId == R.id.md5) {
byteString = byteString.md5();
} else if (algorithmId == R.id.sha1) {
byteString = byteString.sha1();
}
return byteString.hex();
}
@SuppressWarnings("ResultOfMethodCallIgnored")
public static boolean mkdir(File p, boolean allDirs) {
if (p.exists()) return true;
if (allDirs)
p.mkdirs();
else
p.mkdir();
return p.exists();
}
public static long getContentLength(HttpURLConnection connection) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return connection.getContentLengthLong();
}
try {
return Long.parseLong(connection.getHeaderField("Content-Length"));
} catch (Exception err) {
// nothing to do
}
return -1;
}
/**
* Get the content length of the entire file even if the HTTP response is partial
* (response code 206).
* @param connection http connection
* @return content length
*/
public static long getTotalContentLength(final HttpURLConnection connection) {
try {
if (connection.getResponseCode() == 206) {
final String rangeStr = connection.getHeaderField("Content-Range");
final String bytesStr = rangeStr.split("/", 2)[1];
return Long.parseLong(bytesStr);
} else {
return getContentLength(connection);
}
} catch (Exception err) {
// nothing to do
}
return -1;
}
private static String pad(int number) {
return number < 10 ? ("0" + number) : String.valueOf(number);
}
public static String stringifySeconds(final long seconds) {
final int h = (int) Math.floorDiv(seconds, 3600);
final int m = (int) Math.floorDiv(seconds - (h * 3600L), 60);
final int s = (int) (seconds - (h * 3600) - (m * 60));
String str = "";
if (h < 1 && m < 1) {
str = "00:";
} else {
if (h > 0) str = pad(h) + ":";
if (m > 0) str += pad(m) + ":";
}
return str + pad(s);
}
}