Media3 + FFmpeg conversion pipeline #1
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Privacy Policy
|
||||
|
||||
**Media Converter does not collect any data.**
|
||||
**LibreMediaConverter does not collect any data.**
|
||||
|
||||
That is the whole policy, but here is what it means concretely.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Media Converter
|
||||
# LibreMediaConverter
|
||||
|
||||
A free and open-source media converter for Android — batch video transcoding and
|
||||
compression, audio extraction and conversion, GIF and frame export, and file merging.
|
||||
|
||||
@@ -5,14 +5,14 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "dev.jasonmross.mediaconverter"
|
||||
namespace = "org.libremediaconverter"
|
||||
|
||||
compileSdk {
|
||||
version = release(37)
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "dev.jasonmross.mediaconverter"
|
||||
applicationId = "org.libremediaconverter"
|
||||
minSdk = 33
|
||||
// AGP 9 defaults targetSdk to compileSdk, so always state it explicitly.
|
||||
targetSdk = 37
|
||||
|
||||
+11
-11
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.bench
|
||||
package org.libremediaconverter.bench
|
||||
|
||||
import android.media.MediaExtractor
|
||||
import android.media.MediaFormat
|
||||
@@ -8,15 +8,15 @@ import androidx.media3.common.MimeTypes
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import dev.jasonmross.mediaconverter.codec.AndroidDeviceCodecs
|
||||
import dev.jasonmross.mediaconverter.convert.Media3Engine
|
||||
import dev.jasonmross.mediaconverter.convert.MediaProbe
|
||||
import dev.jasonmross.mediaconverter.ffmpeg.FFmpegEngine
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRequest
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRouter
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import dev.jasonmross.mediaconverter.model.VideoCodec
|
||||
import org.libremediaconverter.codec.AndroidDeviceCodecs
|
||||
import org.libremediaconverter.convert.Media3Engine
|
||||
import org.libremediaconverter.convert.MediaProbe
|
||||
import org.libremediaconverter.ffmpeg.FFmpegEngine
|
||||
import org.libremediaconverter.model.ConversionRequest
|
||||
import org.libremediaconverter.model.ConversionRouter
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.model.VideoCodec
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assume.assumeTrue
|
||||
import org.junit.Test
|
||||
@@ -38,7 +38,7 @@ import java.io.File
|
||||
* 2. that x264's CRF is worth the GPL licence the app carries for it.
|
||||
*
|
||||
* Skips itself when the sample files are absent, so it is harmless in CI. Populate with:
|
||||
* adb push <file>.mp4 /sdcard/Android/data/dev.jasonmross.mediaconverter/files/
|
||||
* adb push <file>.mp4 /sdcard/Android/data/org.libremediaconverter/files/
|
||||
*/
|
||||
@UnstableApi
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.convert
|
||||
package org.libremediaconverter.convert
|
||||
|
||||
import android.media.MediaExtractor
|
||||
import android.media.MediaFormat
|
||||
+6
-6
@@ -1,12 +1,12 @@
|
||||
package dev.jasonmross.mediaconverter.fallback
|
||||
package org.libremediaconverter.fallback
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import dev.jasonmross.mediaconverter.convert.ConversionDependencies
|
||||
import dev.jasonmross.mediaconverter.convert.HardwareTranscoder
|
||||
import dev.jasonmross.mediaconverter.convert.OutputPublisher
|
||||
import dev.jasonmross.mediaconverter.convert.SoftwareTranscoder
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRequest
|
||||
import org.libremediaconverter.convert.ConversionDependencies
|
||||
import org.libremediaconverter.convert.HardwareTranscoder
|
||||
import org.libremediaconverter.convert.OutputPublisher
|
||||
import org.libremediaconverter.convert.SoftwareTranscoder
|
||||
import org.libremediaconverter.model.ConversionRequest
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
+8
-8
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.fallback
|
||||
package org.libremediaconverter.fallback
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
@@ -6,13 +6,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import dev.jasonmross.mediaconverter.convert.ConversionDependencies
|
||||
import dev.jasonmross.mediaconverter.model.DeviceCodecs
|
||||
import dev.jasonmross.mediaconverter.model.Engine
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import dev.jasonmross.mediaconverter.work.ConcatWorker
|
||||
import dev.jasonmross.mediaconverter.work.ConversionWorker
|
||||
import org.libremediaconverter.convert.ConversionDependencies
|
||||
import org.libremediaconverter.model.DeviceCodecs
|
||||
import org.libremediaconverter.model.Engine
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.work.ConcatWorker
|
||||
import org.libremediaconverter.work.ConversionWorker
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeout
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.fallback
|
||||
package org.libremediaconverter.fallback
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
@@ -6,9 +6,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import dev.jasonmross.mediaconverter.work.ConversionWorker
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.work.ConversionWorker
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeout
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.fallback
|
||||
package org.libremediaconverter.fallback
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
@@ -8,10 +8,10 @@ import androidx.work.Data
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import dev.jasonmross.mediaconverter.convert.OutputPublisher
|
||||
import dev.jasonmross.mediaconverter.ffmpeg.ConcatEngine
|
||||
import dev.jasonmross.mediaconverter.work.ConcatWorker
|
||||
import dev.jasonmross.mediaconverter.work.ConversionWorker
|
||||
import org.libremediaconverter.convert.OutputPublisher
|
||||
import org.libremediaconverter.ffmpeg.ConcatEngine
|
||||
import org.libremediaconverter.work.ConcatWorker
|
||||
import org.libremediaconverter.work.ConversionWorker
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeout
|
||||
@@ -45,7 +45,7 @@ class UnopenableUriTest {
|
||||
private lateinit var staged: File
|
||||
|
||||
/** A syntactically valid content URI whose authority does not exist. */
|
||||
private val bogus: Uri = Uri.parse("content://dev.jasonmross.nonexistent.provider/media/1")
|
||||
private val bogus: Uri = Uri.parse("content://org.libremediaconverter.nonexistent.provider/media/1")
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
+5
-5
@@ -1,12 +1,12 @@
|
||||
package dev.jasonmross.mediaconverter.ffmpeg
|
||||
package org.libremediaconverter.ffmpeg
|
||||
|
||||
import android.media.MediaExtractor
|
||||
import android.media.MediaFormat
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRequest
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.model.ConversionRequest
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
@@ -28,7 +28,7 @@ import java.io.File
|
||||
class FFmpegEngineTest {
|
||||
|
||||
private val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
private val engine: dev.jasonmross.mediaconverter.convert.SoftwareTranscoder = FFmpegEngine()
|
||||
private val engine: org.libremediaconverter.convert.SoftwareTranscoder = FFmpegEngine()
|
||||
private lateinit var input: File
|
||||
private val outputs = mutableListOf<File>()
|
||||
|
||||
+4
-4
@@ -1,13 +1,13 @@
|
||||
package dev.jasonmross.mediaconverter.join
|
||||
package org.libremediaconverter.join
|
||||
|
||||
import android.media.MediaExtractor
|
||||
import android.media.MediaFormat
|
||||
import android.net.Uri
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import dev.jasonmross.mediaconverter.convert.MediaProbe
|
||||
import dev.jasonmross.mediaconverter.ffmpeg.ConcatEngine
|
||||
import dev.jasonmross.mediaconverter.model.ConcatStrategy
|
||||
import org.libremediaconverter.convert.MediaProbe
|
||||
import org.libremediaconverter.ffmpeg.ConcatEngine
|
||||
import org.libremediaconverter.model.ConcatStrategy
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.join
|
||||
package org.libremediaconverter.join
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
@@ -6,8 +6,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import dev.jasonmross.mediaconverter.model.ConcatStrategy
|
||||
import dev.jasonmross.mediaconverter.work.ConcatWorker
|
||||
import org.libremediaconverter.model.ConcatStrategy
|
||||
import org.libremediaconverter.work.ConcatWorker
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeout
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.work
|
||||
package org.libremediaconverter.work
|
||||
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.net.Uri
|
||||
@@ -8,11 +8,11 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import dev.jasonmross.mediaconverter.codec.AndroidDeviceCodecs
|
||||
import dev.jasonmross.mediaconverter.model.Engine
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import dev.jasonmross.mediaconverter.model.VideoCodec
|
||||
import org.libremediaconverter.codec.AndroidDeviceCodecs
|
||||
import org.libremediaconverter.model.Engine
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.model.VideoCodec
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeout
|
||||
@@ -28,12 +28,12 @@
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.MediaConverter">
|
||||
android:theme="@style/Theme.LibreMediaConverter">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.MediaConverter">
|
||||
android:theme="@style/Theme.LibreMediaConverter">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter
|
||||
package org.libremediaconverter
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
@@ -24,9 +24,9 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import dev.jasonmross.mediaconverter.convert.ConverterScreen
|
||||
import dev.jasonmross.mediaconverter.join.JoinScreen
|
||||
import dev.jasonmross.mediaconverter.ui.theme.MediaConverterTheme
|
||||
import org.libremediaconverter.convert.ConverterScreen
|
||||
import org.libremediaconverter.join.JoinScreen
|
||||
import org.libremediaconverter.ui.theme.LibreMediaConverterTheme
|
||||
|
||||
private enum class Destination(val label: String) {
|
||||
CONVERT("Convert"),
|
||||
@@ -43,7 +43,7 @@ class MainActivity : ComponentActivity() {
|
||||
enableEdgeToEdge()
|
||||
super.onCreate(savedInstanceState)
|
||||
setContent {
|
||||
MediaConverterTheme {
|
||||
LibreMediaConverterTheme {
|
||||
AppRoot(widthSizeClass = calculateWindowSizeClass(this).widthSizeClass)
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
package dev.jasonmross.mediaconverter.codec
|
||||
package org.libremediaconverter.codec
|
||||
|
||||
import android.media.MediaCodecInfo
|
||||
import android.media.MediaCodecList
|
||||
import android.media.MediaFormat
|
||||
import android.util.Log
|
||||
import dev.jasonmross.mediaconverter.model.DeviceCodecs
|
||||
import dev.jasonmross.mediaconverter.model.InputProbe
|
||||
import dev.jasonmross.mediaconverter.model.VideoCodec
|
||||
import org.libremediaconverter.model.DeviceCodecs
|
||||
import org.libremediaconverter.model.InputProbe
|
||||
import org.libremediaconverter.model.VideoCodec
|
||||
|
||||
/**
|
||||
* What this device's codec hardware can actually do.
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.convert
|
||||
package org.libremediaconverter.convert
|
||||
|
||||
import android.app.Application
|
||||
import android.net.Uri
|
||||
@@ -8,10 +8,10 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import dev.jasonmross.mediaconverter.model.EnginePreference
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import dev.jasonmross.mediaconverter.work.ConversionWorker
|
||||
import org.libremediaconverter.model.EnginePreference
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.work.ConversionWorker
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
+8
-8
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.convert
|
||||
package org.libremediaconverter.convert
|
||||
|
||||
import android.Manifest
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
@@ -27,15 +27,15 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.jasonmross.mediaconverter.ui.PrimaryButtonHeight
|
||||
import dev.jasonmross.mediaconverter.ui.ScreenPaddingHorizontal
|
||||
import dev.jasonmross.mediaconverter.ui.ScreenPaddingVertical
|
||||
import org.libremediaconverter.ui.PrimaryButtonHeight
|
||||
import org.libremediaconverter.ui.ScreenPaddingHorizontal
|
||||
import org.libremediaconverter.ui.ScreenPaddingVertical
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import dev.jasonmross.mediaconverter.model.EnginePreference
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.model.EnginePreference
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
import java.util.Locale
|
||||
|
||||
@UnstableApi
|
||||
@@ -72,7 +72,7 @@ fun ConverterScreen(
|
||||
.padding(horizontal = ScreenPaddingHorizontal, vertical = ScreenPaddingVertical),
|
||||
) {
|
||||
Text(
|
||||
"Media Converter",
|
||||
"LibreMediaConverter",
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
modifier = Modifier.padding(bottom = 16.dp),
|
||||
)
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.convert
|
||||
package org.libremediaconverter.convert
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
package dev.jasonmross.mediaconverter.convert
|
||||
package org.libremediaconverter.convert
|
||||
|
||||
import android.content.Context
|
||||
import android.media.MediaExtractor
|
||||
import android.media.MediaFormat
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import dev.jasonmross.mediaconverter.model.ConcatInput
|
||||
import dev.jasonmross.mediaconverter.model.InputProbe
|
||||
import org.libremediaconverter.model.ConcatInput
|
||||
import org.libremediaconverter.model.InputProbe
|
||||
|
||||
/**
|
||||
* Reads just enough about an input to route it.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.convert
|
||||
package org.libremediaconverter.convert
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
+5
-5
@@ -1,11 +1,11 @@
|
||||
package dev.jasonmross.mediaconverter.convert
|
||||
package org.libremediaconverter.convert
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import dev.jasonmross.mediaconverter.ffmpeg.FFmpegEngine
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRequest
|
||||
import dev.jasonmross.mediaconverter.model.DeviceCodecs
|
||||
import dev.jasonmross.mediaconverter.codec.AndroidDeviceCodecs
|
||||
import org.libremediaconverter.ffmpeg.FFmpegEngine
|
||||
import org.libremediaconverter.model.ConversionRequest
|
||||
import org.libremediaconverter.model.DeviceCodecs
|
||||
import org.libremediaconverter.codec.AndroidDeviceCodecs
|
||||
import java.io.File
|
||||
|
||||
/** The hardware conversion path. Implemented by [Media3Engine]. */
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.ffmpeg
|
||||
package org.libremediaconverter.ffmpeg
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
@@ -6,10 +6,10 @@ import android.util.Log
|
||||
import com.arthenica.ffmpegkit.FFmpegKit
|
||||
import com.arthenica.ffmpegkit.FFmpegKitConfig
|
||||
import com.arthenica.ffmpegkit.ReturnCode
|
||||
import dev.jasonmross.mediaconverter.convert.MediaProbe
|
||||
import dev.jasonmross.mediaconverter.model.ConcatPlanner
|
||||
import dev.jasonmross.mediaconverter.model.ConcatStrategy
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.convert.MediaProbe
|
||||
import org.libremediaconverter.model.ConcatPlanner
|
||||
import org.libremediaconverter.model.ConcatStrategy
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import java.io.File
|
||||
import kotlin.coroutines.resume
|
||||
+9
-9
@@ -1,8 +1,8 @@
|
||||
package dev.jasonmross.mediaconverter.ffmpeg
|
||||
package org.libremediaconverter.ffmpeg
|
||||
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRequest
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.model.ConversionRequest
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
|
||||
/**
|
||||
* Builds FFmpeg argument lists.
|
||||
@@ -86,12 +86,12 @@ object FFmpegCommandBuilder {
|
||||
// "compress this well" actually needs. No hardware encoder on Android
|
||||
// exposes it.
|
||||
QualityTier.BEST -> when (format.videoCodec) {
|
||||
dev.jasonmross.mediaconverter.model.VideoCodec.H265 -> listOf(
|
||||
org.libremediaconverter.model.VideoCodec.H265 -> listOf(
|
||||
"-c:v", "libx265", "-crf", "$CRF_H265", "-preset", "medium",
|
||||
// Without this, many players and Apple devices refuse HEVC in MP4.
|
||||
"-tag:v", "hvc1",
|
||||
) + PIX_FMT
|
||||
dev.jasonmross.mediaconverter.model.VideoCodec.VP9 -> listOf(
|
||||
org.libremediaconverter.model.VideoCodec.VP9 -> listOf(
|
||||
"-c:v", "libvpx-vp9", "-crf", "31", "-b:v", "0",
|
||||
) + PIX_FMT
|
||||
else -> listOf(
|
||||
@@ -114,11 +114,11 @@ object FFmpegCommandBuilder {
|
||||
// itself evidence that hardware encoding is unlikely to work for that
|
||||
// input. Fast therefore means a fast *preset*, not a different encoder.
|
||||
QualityTier.FAST -> when (format.videoCodec) {
|
||||
dev.jasonmross.mediaconverter.model.VideoCodec.H265 -> listOf(
|
||||
org.libremediaconverter.model.VideoCodec.H265 -> listOf(
|
||||
"-c:v", "libx265", "-crf", "$CRF_H265", "-preset", "veryfast",
|
||||
"-tag:v", "hvc1",
|
||||
) + PIX_FMT
|
||||
dev.jasonmross.mediaconverter.model.VideoCodec.VP9 -> listOf(
|
||||
org.libremediaconverter.model.VideoCodec.VP9 -> listOf(
|
||||
"-c:v", "libvpx-vp9", "-crf", "31", "-b:v", "0",
|
||||
"-deadline", "realtime",
|
||||
) + PIX_FMT
|
||||
@@ -145,7 +145,7 @@ object FFmpegCommandBuilder {
|
||||
// Move the moov atom to the front so the file starts playing before it is
|
||||
// fully downloaded. This is also the reason output never goes through a SAF
|
||||
// file descriptor: faststart has to seek backwards to rewrite the header.
|
||||
dev.jasonmross.mediaconverter.model.Container.MP4 -> listOf("-movflags", "+faststart")
|
||||
org.libremediaconverter.model.Container.MP4 -> listOf("-movflags", "+faststart")
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
package dev.jasonmross.mediaconverter.ffmpeg
|
||||
package org.libremediaconverter.ffmpeg
|
||||
|
||||
import dev.jasonmross.mediaconverter.model.ConcatStrategy
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.ConcatStrategy
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,7 @@ object FFmpegConcatCommand {
|
||||
add("-safe"); add("0")
|
||||
add("-i"); add(listFile.absolutePath)
|
||||
add("-c"); add("copy")
|
||||
if (format.container == dev.jasonmross.mediaconverter.model.Container.MP4) {
|
||||
if (format.container == org.libremediaconverter.model.Container.MP4) {
|
||||
add("-movflags"); add("+faststart")
|
||||
}
|
||||
add(output.absolutePath)
|
||||
@@ -60,7 +60,7 @@ object FFmpegConcatCommand {
|
||||
add("-crf"); add("20")
|
||||
add("-pix_fmt"); add("yuv420p")
|
||||
add("-c:a"); add("aac")
|
||||
if (format.container == dev.jasonmross.mediaconverter.model.Container.MP4) {
|
||||
if (format.container == org.libremediaconverter.model.Container.MP4) {
|
||||
add("-movflags"); add("+faststart")
|
||||
}
|
||||
add(output.absolutePath)
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
package dev.jasonmross.mediaconverter.ffmpeg
|
||||
package org.libremediaconverter.ffmpeg
|
||||
|
||||
import android.util.Log
|
||||
import com.arthenica.ffmpegkit.FFmpegKit
|
||||
import com.arthenica.ffmpegkit.FFmpegKitConfig
|
||||
import com.arthenica.ffmpegkit.Level
|
||||
import com.arthenica.ffmpegkit.ReturnCode
|
||||
import dev.jasonmross.mediaconverter.convert.SoftwareTranscoder
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRequest
|
||||
import org.libremediaconverter.convert.SoftwareTranscoder
|
||||
import org.libremediaconverter.model.ConversionRequest
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import java.io.File
|
||||
import kotlin.coroutines.resume
|
||||
@@ -18,7 +18,7 @@ import kotlin.coroutines.resumeWithException
|
||||
* Handles everything Media3 structurally cannot: Matroska, MP3, GIF, frame sequences,
|
||||
* inputs with no platform decoder, and the CRF quality tier.
|
||||
*
|
||||
* Like [dev.jasonmross.mediaconverter.convert.Media3Engine], input arrives as a real
|
||||
* Like [org.libremediaconverter.convert.Media3Engine], input arrives as a real
|
||||
* filesystem path and output is written to app-private cache. FFmpeg is perfectly able
|
||||
* to write through a SAF descriptor via its ffkitsaf protocol, but MP4 faststart has
|
||||
* to seek backwards to rewrite the moov atom, which a SAF descriptor does not reliably
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.join
|
||||
package org.libremediaconverter.join
|
||||
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
@@ -25,11 +25,11 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import dev.jasonmross.mediaconverter.convert.InputFile
|
||||
import dev.jasonmross.mediaconverter.model.ConcatStrategy
|
||||
import dev.jasonmross.mediaconverter.ui.PrimaryButtonHeight
|
||||
import dev.jasonmross.mediaconverter.ui.ScreenPaddingHorizontal
|
||||
import dev.jasonmross.mediaconverter.ui.ScreenPaddingVertical
|
||||
import org.libremediaconverter.convert.InputFile
|
||||
import org.libremediaconverter.model.ConcatStrategy
|
||||
import org.libremediaconverter.ui.PrimaryButtonHeight
|
||||
import org.libremediaconverter.ui.ScreenPaddingHorizontal
|
||||
import org.libremediaconverter.ui.ScreenPaddingVertical
|
||||
|
||||
@UnstableApi
|
||||
@Composable
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.join
|
||||
package org.libremediaconverter.join
|
||||
|
||||
import android.app.Application
|
||||
import android.net.Uri
|
||||
@@ -8,10 +8,10 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import dev.jasonmross.mediaconverter.convert.InputFile
|
||||
import dev.jasonmross.mediaconverter.convert.OutputPublisher
|
||||
import dev.jasonmross.mediaconverter.model.ConcatStrategy
|
||||
import dev.jasonmross.mediaconverter.work.ConcatWorker
|
||||
import org.libremediaconverter.convert.InputFile
|
||||
import org.libremediaconverter.convert.OutputPublisher
|
||||
import org.libremediaconverter.model.ConcatStrategy
|
||||
import org.libremediaconverter.work.ConcatWorker
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.model
|
||||
package org.libremediaconverter.model
|
||||
|
||||
/**
|
||||
* How to join several inputs into one file.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.model
|
||||
package org.libremediaconverter.model
|
||||
|
||||
/**
|
||||
* Chooses the engine for a conversion.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.model
|
||||
package org.libremediaconverter.model
|
||||
|
||||
/** Container families, used by the router to decide which engine can mux the result. */
|
||||
enum class Container { MP4, WEBM, MKV, OGG, WAV, AAC_ADTS, MP3, GIF, IMAGE_SEQUENCE }
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.ui
|
||||
package org.libremediaconverter.ui
|
||||
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.ui.theme
|
||||
package org.libremediaconverter.ui.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.ui.theme
|
||||
package org.libremediaconverter.ui.theme
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
@@ -30,7 +30,7 @@ private val LightColorScheme = lightColorScheme(
|
||||
* opt back to the brand palette.
|
||||
*/
|
||||
@Composable
|
||||
fun MediaConverterTheme(
|
||||
fun LibreMediaConverterTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
dynamicColor: Boolean = true,
|
||||
content: @Composable () -> Unit,
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.ui.theme
|
||||
package org.libremediaconverter.ui.theme
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.work
|
||||
package org.libremediaconverter.work
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
@@ -11,9 +11,9 @@ import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dev.jasonmross.mediaconverter.convert.ConversionDependencies
|
||||
import dev.jasonmross.mediaconverter.ffmpeg.ConcatEngine
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.convert.ConversionDependencies
|
||||
import org.libremediaconverter.ffmpeg.ConcatEngine
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
|
||||
/**
|
||||
* Joins several files into one, as durable foreground work.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.work
|
||||
package org.libremediaconverter.work
|
||||
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.os.Build
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.work
|
||||
package org.libremediaconverter.work
|
||||
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
@@ -6,7 +6,7 @@ import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.work.WorkManager
|
||||
import dev.jasonmross.mediaconverter.R
|
||||
import org.libremediaconverter.R
|
||||
import java.util.UUID
|
||||
|
||||
/** Progress notification for a running conversion. */
|
||||
+10
-10
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.work
|
||||
package org.libremediaconverter.work
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
@@ -13,15 +13,15 @@ import androidx.work.WorkInfo
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import com.arthenica.ffmpegkit.FFmpegKitConfig
|
||||
import dev.jasonmross.mediaconverter.convert.ConversionDependencies
|
||||
import dev.jasonmross.mediaconverter.convert.MediaProbe
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRequest
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRouter
|
||||
import dev.jasonmross.mediaconverter.model.Engine
|
||||
import dev.jasonmross.mediaconverter.model.EnginePreference
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import dev.jasonmross.mediaconverter.model.VideoCodec
|
||||
import org.libremediaconverter.convert.ConversionDependencies
|
||||
import org.libremediaconverter.convert.MediaProbe
|
||||
import org.libremediaconverter.model.ConversionRequest
|
||||
import org.libremediaconverter.model.ConversionRouter
|
||||
import org.libremediaconverter.model.Engine
|
||||
import org.libremediaconverter.model.EnginePreference
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.model.VideoCodec
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.work
|
||||
package org.libremediaconverter.work
|
||||
|
||||
import androidx.work.WorkInfo
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<resources>
|
||||
<style name="Theme.MediaConverter" parent="android:Theme.Material.NoActionBar" />
|
||||
<style name="Theme.LibreMediaConverter" parent="android:Theme.Material.NoActionBar" />
|
||||
</resources>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">Media Converter</string>
|
||||
<string name="app_name">LibreMediaConverter</string>
|
||||
|
||||
<string name="channel_conversions">Conversions</string>
|
||||
<string name="channel_conversions_description">Progress for running conversions</string>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<resources>
|
||||
<style name="Theme.MediaConverter" parent="android:Theme.Material.Light.NoActionBar" />
|
||||
<style name="Theme.LibreMediaConverter" parent="android:Theme.Material.Light.NoActionBar" />
|
||||
</resources>
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
package dev.jasonmross.mediaconverter.ffmpeg
|
||||
package org.libremediaconverter.ffmpeg
|
||||
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRequest
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import dev.jasonmross.mediaconverter.model.QualityTier
|
||||
import org.libremediaconverter.model.ConversionRequest
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.QualityTier
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package dev.jasonmross.mediaconverter.ffmpeg
|
||||
package org.libremediaconverter.ffmpeg
|
||||
|
||||
import dev.jasonmross.mediaconverter.model.ConcatStrategy
|
||||
import dev.jasonmross.mediaconverter.model.OutputFormat
|
||||
import org.libremediaconverter.model.ConcatStrategy
|
||||
import org.libremediaconverter.model.OutputFormat
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.model
|
||||
package org.libremediaconverter.model
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package dev.jasonmross.mediaconverter.model
|
||||
package org.libremediaconverter.model
|
||||
|
||||
import dev.jasonmross.mediaconverter.model.ConversionRouter.Reason
|
||||
import org.libremediaconverter.model.ConversionRouter.Reason
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.model
|
||||
package org.libremediaconverter.model
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.jasonmross.mediaconverter.work
|
||||
package org.libremediaconverter.work
|
||||
|
||||
import androidx.work.WorkInfo
|
||||
import org.junit.Assert.assertEquals
|
||||
@@ -1 +1 @@
|
||||
Media Converter
|
||||
LibreMediaConverter
|
||||
|
||||
+1
-1
@@ -22,5 +22,5 @@ dependencyResolutionManagement {
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "AndroidMediaConverter"
|
||||
rootProject.name = "LibreMediaConverter"
|
||||
include(":app")
|
||||
|
||||
Reference in New Issue
Block a user