Skip to content

Commit

Permalink
Releases/v0.4.2 (#80)
Browse files Browse the repository at this point in the history
## New

* feat: Add `UploadResult` class for java users to interpret Result (#73)

## Fixes

* Fix: Some methods on MuxUpload.Builder don't return Builder (#74)
* Fix: the application context shouldn't be visible (#76)
* Fix: Transcoding errors handled incorrectly (#79)



Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Emily Dixon <edixon@mux.com>
Co-authored-by: Tomislav Kordic <32546640+tomkordic@users.noreply.github.com>
Co-authored-by: GitHub <noreply@github.com>
  • Loading branch information
4 people committed Jul 31, 2023
1 parent 6510676 commit 9bd7e8a
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 64 deletions.
7 changes: 4 additions & 3 deletions library/src/main/java/com/mux/video/upload/MuxUploadSdk.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ object MuxUploadSdk {
@Suppress("unused")
@JvmOverloads
fun initialize(appContext: Context, resumeStoppedUploads: Boolean = true) {
MuxUploadManager.appContext = appContext;
initializeUploadPersistence(appContext)
UploadMetrics.initialize(appContext)
val realAppContext = appContext.applicationContext // Just in case they give us something else
MuxUploadManager.appContext = realAppContext
initializeUploadPersistence(realAppContext)
UploadMetrics.initialize(realAppContext)
if (resumeStoppedUploads) {
MuxUploadManager.resumeAllCachedJobs()
}
Expand Down
6 changes: 4 additions & 2 deletions library/src/main/java/com/mux/video/upload/api/MuxUpload.kt
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,9 @@ class MuxUpload private constructor(
* for use with Mux Video
*/
@Suppress("unused")
fun standardizationRequested(enabled: Boolean) {
fun standardizationRequested(enabled: Boolean): Builder {
uploadInfo.update(standardizationRequested = enabled)
return this
}

/**
Expand All @@ -373,8 +374,9 @@ class MuxUpload private constructor(
* here.
*/
@Suppress("unused")
fun optOutOfEventTracking(optOut: Boolean) {
fun optOutOfEventTracking(optOut: Boolean): Builder {
uploadInfo.update(optOut = optOut)
return this
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ import java.io.File
*/
object MuxUploadManager {

public var appContext: Context? = null;
private val mainScope = MainScope()

private val uploadsByFilename: MutableMap<String, UploadInfo> = mutableMapOf()
private val observerJobsByFilename: MutableMap<String, Job> = mutableMapOf()
private val listeners: MutableSet<UploadEventListener<List<MuxUpload>>> = mutableSetOf()
private val logger get() = MuxUploadSdk.logger
@Suppress("unused")
private val logger by MuxUploadSdk::logger

@JvmSynthetic
internal var appContext: Context? = null

/**
* Finds an in-progress, paused, or failed upload and returns a [MuxUpload] to track it, if it was
Expand Down Expand Up @@ -182,5 +184,4 @@ object MuxUploadManager {
}
}
}

}
56 changes: 56 additions & 0 deletions library/src/main/java/com/mux/video/upload/api/UploadResult.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.mux.video.upload.api

/**
* Helper class for parsing [Result] objects from [MuxUpload] in Java.
*
* Kotlin callers can use the [Result] API as normal
*/
class UploadResult {

companion object {
/**
* Returns true of the upload was successful,
* Returns false if the upload wasn't successful, or if the passed object wasn't a [Result]
*/
@Suppress("unused")
@JvmStatic
fun isSuccessful(result: Result<MuxUpload.Progress>): Boolean {
@Suppress("USELESS_IS_CHECK") // java interprets inline classes like Result as Object
return if (result is Result) {
result.isSuccess
} else {
false
}

}

/**
* Returns the final Progress update from [MuxUpload]'s [Result] if if was successful
* Returns `null` if the upload was not successful, or if the passed object wasn't a result
*/
@Suppress("unused")
@JvmStatic
fun getFinalProgress(result: Result<MuxUpload.Progress>): MuxUpload.Progress? {
@Suppress("USELESS_IS_CHECK") // java interprets inline classes like Result as Object
return if (result is Result) {
result.getOrNull()
} else {
null
}
}

/**
* If the Result was not successful, returns the Exception that caused the failure
*/
@Suppress("unused")
@JvmStatic
fun getError(result: Result<MuxUpload.Progress>): Throwable? {
@Suppress("USELESS_IS_CHECK") // java interprets inline classes like Result as Object
return if (result is Result) {
result.exceptionOrNull()
} else {
null
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ sealed class UploadStatus {
*/
open fun getError(): Exception? = null

/**
* Returns whether or not the uplod was successful
*/
@Suppress("unused")
fun isSuccessful(): Boolean = this is UploadSuccess

// Subclasses

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ internal class TranscoderContext private constructor(
uploadInfo = uploadInfo.update(standardizedFile = destFile)

try {
extractor.setDataSource(uploadInfo.inputFile.absolutePath)
configureDecoders()
configured = true
} catch (e:Exception) {
Expand All @@ -117,66 +116,78 @@ internal class TranscoderContext private constructor(

private fun checkIfTranscodingIsNeeded(): Boolean {
var shouldStandardize = false
for (i in 0 until extractor.trackCount) {
val format = extractor.getTrackFormat(i)
val mime = format.getString(MediaFormat.KEY_MIME)
var inputDuration:Long = -1;
if (mime?.lowercase()?.contains("video") == true) {
inputWidth = format.getInteger(MediaFormat.KEY_WIDTH)
inputHeighth = format.getInteger(MediaFormat.KEY_HEIGHT)
// Check if resolution is greater then 720p
if ((inputWidth > MAX_ALLOWED_WIDTH && inputHeighth > MAX_ALLOWED_HEIGTH)
|| (inputHeighth > MAX_ALLOWED_WIDTH && inputWidth > MAX_ALLOWED_HEIGTH)) {
logger.v(LOG_TAG, "Should standardize because the size is incorrect")
shouldStandardize = true
if(inputWidth > inputHeighth) {
targetedWidth = MAX_ALLOWED_WIDTH
targetedHeight = targetedWidth * (inputHeighth / inputWidth)
try {
extractor.setDataSource(uploadInfo.inputFile.absolutePath)
for (i in 0 until extractor.trackCount) {
val format = extractor.getTrackFormat(i)
val mime = format.getString(MediaFormat.KEY_MIME)
var inputDuration: Long = -1;
if (mime?.lowercase()?.contains("video") == true) {
inputWidth = format.getInteger(MediaFormat.KEY_WIDTH)
inputHeighth = format.getInteger(MediaFormat.KEY_HEIGHT)
// Check if resolution is greater then 720p
if ((inputWidth > MAX_ALLOWED_WIDTH && inputHeighth > MAX_ALLOWED_HEIGTH)
|| (inputHeighth > MAX_ALLOWED_WIDTH && inputWidth > MAX_ALLOWED_HEIGTH)
) {
logger.v(LOG_TAG, "Should standardize because the size is incorrect")
shouldStandardize = true
if (inputWidth > inputHeighth) {
targetedWidth = MAX_ALLOWED_WIDTH
targetedHeight = targetedWidth * (inputHeighth / inputWidth)
} else {
targetedHeight = MAX_ALLOWED_WIDTH
targetedWidth = targetedHeight * (inputWidth / inputHeighth)
}
} else {
targetedHeight = MAX_ALLOWED_WIDTH
targetedWidth = targetedHeight * (inputWidth / inputHeighth)
targetedWidth = inputWidth
targetedHeight = inputHeighth
}
} else {
targetedWidth = inputWidth
targetedHeight = inputHeighth
}
scaledSizeYuv = Nv12Buffer.allocate(targetedWidth, targetedHeight)
scaledSizeYuv = Nv12Buffer.allocate(targetedWidth, targetedHeight)

// Check if compersion is h264
if (!mime.equals(MediaFormat.MIMETYPE_VIDEO_AVC)) {
logger.v(LOG_TAG, "Should standardize because the input is not h.264")
shouldStandardize = true
}
inputBitrate = format.getIntegerCompat(MediaFormat.KEY_BIT_RATE, -1)
inputDuration = format.getLongCompat(MediaFormat.KEY_DURATION, -1)
if (inputBitrate == -1 && inputDuration != -1L) {
inputBitrate = ((uploadInfo.inputFile.length() * 8) / (inputDuration / 1000000)).toInt()
}
if (inputBitrate > MAX_ALLOWED_BITRATE) {
logger.v(LOG_TAG, "Should standardize because the input bitrate is too high")
shouldStandardize = true
targetedBitrate = MAX_ALLOWED_BITRATE
// Check if compersion is h264
if (!mime.equals(MediaFormat.MIMETYPE_VIDEO_AVC)) {
logger.v(LOG_TAG, "Should standardize because the input is not h.264")
shouldStandardize = true
}
inputBitrate = format.getIntegerCompat(MediaFormat.KEY_BIT_RATE, -1)
inputDuration = format.getLongCompat(MediaFormat.KEY_DURATION, -1)
if (inputBitrate == -1 && inputDuration != -1L) {
inputBitrate =
((uploadInfo.inputFile.length() * 8) / (inputDuration / 1000000)).toInt()
}
if (inputBitrate > MAX_ALLOWED_BITRATE) {
logger.v(
LOG_TAG,
"Should standardize because the input bitrate is too high"
)
shouldStandardize = true
targetedBitrate = MAX_ALLOWED_BITRATE
}
inputFramerate = format.getIntegerCompat(MediaFormat.KEY_FRAME_RATE, -1)
if (inputFramerate > MAX_ALLOWED_FRAMERATE) {
logger.v(
LOG_TAG,
"Should standardize because the input frame rate is too high"
)
shouldStandardize = true
targetedFramerate = OPTIMAL_FRAMERATE
} else {
targetedFramerate = inputFramerate
}
videoTrackIndex = i;
inputVideoFormat = format;
extractor.selectTrack(i)
}
inputFramerate = format.getIntegerCompat(MediaFormat.KEY_FRAME_RATE, -1)
if (inputFramerate > MAX_ALLOWED_FRAMERATE) {
logger.v(LOG_TAG, "Should standardize because the input frame rate is too high")
shouldStandardize = true
targetedFramerate = OPTIMAL_FRAMERATE
} else {
targetedFramerate = inputFramerate
if (mime?.lowercase()?.contains("audio") == true) {
// TODO check if audio need to be standardized
audioTrackIndex = i;
inputAudioFormat = format;
extractor.selectTrack(i)
}
videoTrackIndex = i;
inputVideoFormat = format;
extractor.selectTrack(i)
}
if (mime?.lowercase()?.contains("audio") == true) {
// TODO check if audio need to be standardized
audioTrackIndex = i;
inputAudioFormat = format;
extractor.selectTrack(i)
}
} catch (ex:Exception) {
ex.printStackTrace()
}

return shouldStandardize
}

Expand Down Expand Up @@ -314,11 +325,12 @@ internal class TranscoderContext private constructor(
videoDecoder!!.flush()
videoEncoder!!.flush()
muxVideoFrame()
muxer!!.stop()
fileTranscoded = true
} catch (err:Exception) {
logger.e(LOG_TAG, "Failed to standardize input file ${uploadInfo.inputFile}", err)
} finally {
releaseCodecs()
fileTranscoded = true
}
val duration = System.currentTimeMillis() - started
logger.i(LOG_TAG, "Transcoding duration time: $duration")
Expand Down

0 comments on commit 9bd7e8a

Please sign in to comment.