動画の再エンコード時にピクセルサイズが奇数にならないようにする
This commit is contained in:
parent
5280e7f2be
commit
55fb631952
|
@ -97,13 +97,11 @@ class AttachmentRequest(
|
||||||
suspend fun createOpener(): InputStreamOpener {
|
suspend fun createOpener(): InputStreamOpener {
|
||||||
val mimeType = this.mimeType
|
val mimeType = this.mimeType
|
||||||
|
|
||||||
// GIFはそのまま投げる
|
|
||||||
if (mimeType == MIME_TYPE_GIF) {
|
if (mimeType == MIME_TYPE_GIF) {
|
||||||
|
// GIFはそのまま投げる
|
||||||
return contentUriOpener(context.contentResolver, uri, mimeType, isImage = true)
|
return contentUriOpener(context.contentResolver, uri, mimeType, isImage = true)
|
||||||
}
|
}else if (mimeType.startsWith("image")) {
|
||||||
|
// 静止画
|
||||||
// 静止画
|
|
||||||
if (mimeType.startsWith("image")) {
|
|
||||||
return createResizedImageOpener()
|
return createResizedImageOpener()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,36 @@ data class MovieResizeConfig(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* レシーバが奇数なら+1した値を返す
|
||||||
|
*
|
||||||
|
* `[OMX.qcom.video.encoder.avc] video encoder does not support odd resolution 1018x2263`
|
||||||
|
*/
|
||||||
|
private fun Int.fixOdd() = if (and(1) == 0) this else this + 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 動画のピクセルサイズを制限に合わせてスケーリングする
|
||||||
|
*/
|
||||||
|
private fun createScaledSize(inSize: Size, limitSquarePixels: Int): Size {
|
||||||
|
|
||||||
|
if (inSize.major <= 0 || inSize.minor <= 0) {
|
||||||
|
// 入力サイズの縦横が0以下の場合、アスペクト比を計算できないのでリサイズできない
|
||||||
|
log.w("createScaledSize: video size not valid. major=${inSize.major}, minor=${inSize.minor}")
|
||||||
|
return inSize
|
||||||
|
}
|
||||||
|
|
||||||
|
val squarePixels = inSize.major * inSize.minor
|
||||||
|
if (squarePixels <= limitSquarePixels) {
|
||||||
|
return inSize
|
||||||
|
}
|
||||||
|
|
||||||
|
val aspect = inSize.major.toFloat() / inSize.minor.toFloat()
|
||||||
|
return Size(
|
||||||
|
max(1f, sqrt(limitSquarePixels.toFloat() * aspect)).toInt().fixOdd(),
|
||||||
|
max(1f, sqrt(limitSquarePixels.toFloat() / aspect)).toInt().fixOdd(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
suspend fun transcodeVideo(
|
suspend fun transcodeVideo(
|
||||||
info: VideoInfo,
|
info: VideoInfo,
|
||||||
|
@ -122,19 +152,10 @@ suspend fun transcodeVideo(
|
||||||
.addDataSource(inStream.fd)
|
.addDataSource(inStream.fd)
|
||||||
.setVideoTrackStrategy(DefaultVideoStrategy.Builder()
|
.setVideoTrackStrategy(DefaultVideoStrategy.Builder()
|
||||||
.addResizer { inSize ->
|
.addResizer { inSize ->
|
||||||
val squarePixels = inSize.major * inSize.minor
|
createScaledSize(
|
||||||
val limit = resizeConfig.limitSquarePixels
|
inSize = inSize,
|
||||||
if (squarePixels <= limit || inSize.major <= 0 || inSize.minor <= 0) {
|
limitSquarePixels = resizeConfig.limitSquarePixels
|
||||||
// 入力サイズが0以下の場合もアスペクト計算に支障がでるのでリサイズできない
|
)
|
||||||
inSize
|
|
||||||
} else {
|
|
||||||
// アスペクト比を維持しつつ平方ピクセルが指定に収まるようにする
|
|
||||||
val aspect = inSize.major.toFloat() / inSize.minor.toFloat()
|
|
||||||
Size(
|
|
||||||
max(1, (sqrt(limit.toFloat() * aspect) + 0.5f).toInt()),
|
|
||||||
max(1, (sqrt(limit.toFloat() / aspect) + 0.5f).toInt()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.frameRate(resizeConfig.limitFrameRate)
|
.frameRate(resizeConfig.limitFrameRate)
|
||||||
.keyFrameInterval(10f)
|
.keyFrameInterval(10f)
|
||||||
|
|
Loading…
Reference in New Issue