Skip to content
Snippets Groups Projects
Commit 05bcc64c authored by Sofiane Lasri's avatar Sofiane Lasri
Browse files

base

parents
No related branches found
No related tags found
No related merge requests found
Pipeline #9 failed
Showing
with 899 additions and 0 deletions
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
# Default ignored files
/shelf/
/workspace.xml
SL-Video Compressor
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<multipleDevicesSelectedInDropDown value="true" />
<runningDeviceTargetsSelectedWithDialog>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="R3CR60HNFLW" />
</Key>
</deviceKey>
</Target>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="da1d6329" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetsSelectedWithDialog>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/Users/sofia/Documents/GitHub/sl-video-compressor/app/src/main/res/layout/activity_main.xml" value="0.264" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
/build
\ No newline at end of file
plugins {
id 'com.android.application'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.slprojects.sl_videocompressor"
minSdk 24
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'com.arthenica:ffmpeg-kit-full:4.5.1-1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
package com.slprojects.sl_videocompressor;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.slprojects.sl_videocompressor", appContext.getPackageName());
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.slprojects.sl_videocompressor">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:requestLegacyExternalStorage="true"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.SLVideoCompressor">
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
package com.slprojects.sl_videocompressor;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import java.io.File;
public class FileUtils {
// Get a file from a Uri.
// Framework Documents, as well as the _data field for the MediaStore and
// other file-based ContentProviders.
// @param context The context.
// @param uri The Uri to query
public static File getFileFromUri(final Context context, final Uri uri) throws Exception {
String path = null;
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (DocumentsContract.isDocumentUri(context, uri)) { // TODO: 2015. 11. 17. KITKAT
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
path = Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
} else if (isDownloadsDocument(uri)) { // DownloadsProvider
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
path = getDataColumn(context, contentUri, null, null);
} else if (isMediaDocument(uri)) { // MediaProvider
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
path = getDataColumn(context, contentUri, selection, selectionArgs);
} // MediaStore (and general)
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
path = getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
path = uri.getPath();
}
return new File(path);
} else {
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
return new File(cursor.getString(cursor.getColumnIndexOrThrow("_data")));
}
}
// Get the value of the data column for this Uri. This is useful for
// MediaStore Uris, and other file-based ContentProviders.
// @param context The context.
// @param uri The Uri to query.
// @param selection (Optional) Filter used in the query.
// @param selectionArgs (Optional) Selection arguments used in the query.
// @return The value of the _data column, which is typically a file path.
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = MediaStore.Images.Media.DATA;
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
// @param uri The Uri to check.
// @return Whether the Uri authority is ExternalStorageProvide
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
// @param uri The Uri to check.
// @return Whether the Uri authority is DownloadsProvider.
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
// @param uri The Uri to check.
// @return Whether the Uri authority is MediaProvider.
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}
package com.slprojects.sl_videocompressor;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.arthenica.ffmpegkit.FFmpegKit;
import com.arthenica.ffmpegkit.FFmpegSession;
import com.arthenica.ffmpegkit.ReturnCode;
import java.io.File;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button chooseFileBtn;
private TextView videoInformations;
private String video_url;
private LinearLayout weHaveTheVideo;
private Spinner sizeUnit;
private EditText targetFileSizeInput;
private Spinner encodeQuality;
private Button encodeVideoBtn;
private CheckBox deleteSoundTrack;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// On retire le titre de l'application
getSupportActionBar().hide();
// On va vérifier que l'on a bien les permissions
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
// On demande les permissions
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
// On demande les permissions
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
chooseFileBtn = findViewById(R.id.chooseFileBtn);
chooseFileBtn.setOnClickListener((View.OnClickListener) this);
videoInformations = findViewById(R.id.videoInformations);
weHaveTheVideo = findViewById(R.id.weHaveTheVideo);
sizeUnit = findViewById(R.id.sizeUnit);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.size_units, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sizeUnit.setAdapter(adapter);
encodeQuality = findViewById(R.id.encodeQuality);
targetFileSizeInput = findViewById(R.id.targetFileSizeInput);
ArrayAdapter<CharSequence> adapter2 = ArrayAdapter.createFromResource(this, R.array.encode_qualities, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
encodeQuality.setAdapter(adapter2);
encodeVideoBtn = findViewById(R.id.encodeVideoBtn);
encodeVideoBtn.setOnClickListener((View.OnClickListener) this);
deleteSoundTrack = findViewById(R.id.deleteSoundTrack);
}
@Override
public void onClick(View v){
if(v == chooseFileBtn){
// On va lancer l'activité de choix de fichier
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
intent.setType("video/*");
startActivityForResult(intent, 123);
}else if(v == encodeVideoBtn){
Log.d("MainActivity", "Encode video");
// On va vérifier que l'utilisateur a renté une taille de fichier
if(targetFileSizeInput.getText().toString().equals("")){
Toast.makeText(this, "Veuillez rentrer une taille de fichier", Toast.LENGTH_SHORT).show();
return;
}
// Mais aussi qu'il a bien choisir une qualité
if(encodeQuality.getSelectedItem().toString().equals("")){
Toast.makeText(this, "Veuillez choisir une qualité", Toast.LENGTH_SHORT).show();
return;
}
// On peut lancer l'encodage
encodeVideo(video_url, targetFileSizeInput.getText().toString(), encodeQuality.getSelectedItem().toString());
}
}
// Overriding the method onActivityResult()
// to get the video Uri form intent.
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == 123) {
if (data != null) {
// get the video Uri
Uri uri = data.getData();
try {
// get the file from the Uri using getFileFromUri() method present
// in FileUils.java
File video_file = FileUtils.getFileFromUri(this, uri);
// get the absolute path of the video file. We will require
// this as an input argument in
// the ffmpeg command.
video_url = video_file.getAbsolutePath();
aVideoHasBeenChoosen();
} catch (Exception e) {
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
}
}
public void aVideoHasBeenChoosen() {
String video_name = video_url.substring(video_url.lastIndexOf("/") + 1);
chooseFileBtn.setText(video_name);
String affichage = "Nom : " + video_name + "\n" + "Durée : " + getVideoDuration(video_url) + "\n" + "Taille : " + getVideoSize(video_url);
videoInformations.setText(affichage);
videoInformations.setMaxLines(affichage.split("\n").length);
weHaveTheVideo.setVisibility(View.VISIBLE);
}
// Fonction affichages
public String getVideoDuration(String video_url) {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(video_url);
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long timeInMillisec = Long.parseLong(time);
long duration = timeInMillisec / 1000;
long hours = duration / 3600;
long minutes = (duration - hours * 3600) / 60;
long seconds = duration - (hours * 3600 + minutes * 60);
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
public String getVideoSize(String video_url) {
File file = new File(video_url);
long size = file.length();
return String.format("%d Mo", size / 1000000);
}
// Fonction d'encodage
public Integer getVideoDurationInSeconds(String video_url) {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(video_url);
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long timeInMillisec = Long.parseLong(time);
return (int) timeInMillisec;
}
public Integer getVideoSizeInBytes(String video_url) {
File file = new File(video_url);
long size = file.length();
return (int) size;
}
// Fonction de conversion
public void encodeVideo(String video_url, String targetFileSize, String quality) {
// On récupère la taille cible du fichier selon l'unité choisie
Integer targetFileSizeInKiloBit = 0;
if(sizeUnit.getSelectedItem().toString().equals("Mo")) {
targetFileSizeInKiloBit = Integer.parseInt(targetFileSize) * 1000 * 8;
}else if(sizeUnit.getSelectedItem().toString().equals("MB")) {
targetFileSizeInKiloBit = Integer.parseInt(targetFileSize) * 1000 * 8;
}else{
Toast.makeText(this, "Unité de taille \"" + sizeUnit.getSelectedItem().toString() + "\" non reconnue. M", Toast.LENGTH_SHORT).show();
}
// On va appliquer une marge de 10% à la taille cible
targetFileSizeInKiloBit = (int) targetFileSizeInKiloBit * 9 / 10;
Log.d("targetFileSizeInKiloBit", targetFileSizeInKiloBit.toString());
// On récupère la durée de la vidéo
Integer videoDurationInSeconds = getVideoDurationInSeconds(video_url);
// On regarde si on garde l'audio ou pas
Integer audioBitrate = 0; // en kBits
if(!deleteSoundTrack.isChecked()) {
audioBitrate = 128;
}
// On va calculer le bitrate de la video en fonction de la bande son
Integer videoBitrate = (int) (targetFileSizeInKiloBit / videoDurationInSeconds) - audioBitrate;
String outputFileName = video_url.substring(0, video_url.length() - 4) + "_" + targetFileSize + "_" + quality + ".mp4";
String ffmpegCommand = "-i " + video_url + " -b:v " + videoBitrate + "k -c:a aac -b:a " + audioBitrate + "k " + outputFileName;
Log.d("FFMPEG", ffmpegCommand);
// On lance l'encodage
Toast.makeText(this, "Encodage en cours...", Toast.LENGTH_SHORT).show();
encodeVideoBtn.setEnabled(false);
FFmpegSession session = FFmpegKit.execute(ffmpegCommand);
if (ReturnCode.isSuccess(session.getReturnCode())) {
// SUCCESS
Toast.makeText(this, "Encodage terminé: " + outputFileName, Toast.LENGTH_LONG).show();
} else if (ReturnCode.isCancel(session.getReturnCode())) {
// CANCEL
} else {
// FAILURE
Log.d("Main", String.format("Command failed with state %s and rc %s.%s", session.getState(), session.getReturnCode(), session.getFailStackTrace()));
Toast.makeText(this, "Erreur lors de l'encodage de la vidéo", Toast.LENGTH_SHORT).show();
}
encodeVideoBtn.setEnabled(true);
}
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Choisissez un fichie à compresser"
android:textStyle="bold" />
<Button
android:id="@+id/chooseFileBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Choisir un fichier" />
<LinearLayout
android:id="@+id/weHaveTheVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="invisible"
tools:visibility="visible">
<TextView
android:id="@+id/videoInformations"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="@+id/chooseTargetSize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Taille cible"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/targetFileSizeInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="number" />
<Spinner
android:id="@+id/sizeUnit"
android:layout_width="150dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Qualité d'encodage"
android:textStyle="bold" />
<Spinner
android:id="@+id/encodeQuality"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/deleteSoundTrack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Couper le son" />
<Button
android:id="@+id/encodeVideoBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Compresser"
tools:layout_editor_absoluteX="-98dp"
tools:layout_editor_absoluteY="587dp" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment