Раньше я создал и даже поделился примером создания файла MP4 из серии растровых изображений, здесь, на основе на здесь, а также я опубликовал код на Github, здесь.
Кажется, он отлично работает с одним изображением. , как таковой:
Код: Выделить всё
@WorkerThread
private fun testImage() {
Log.d("AppLog", "testImage")
val startTime = System.currentTimeMillis()
Log.d("AppLog", "start")
val videoFile = File(ContextCompat.getExternalFilesDirs(this, null)[0], "image.mp4")
if (videoFile.exists())
videoFile.delete()
videoFile.parentFile!!.mkdirs()
val timeLapseEncoder = TimeLapseEncoder()
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.test)
val width = bitmap.width
val height = bitmap.height
timeLapseEncoder.prepareForEncoding(videoFile.absolutePath, width, height)
val frameDurationInMs = 1000
timeLapseEncoder.encodeFrame(bitmap, frameDurationInMs)
timeLapseEncoder.finishEncoding()
val endTime = System.currentTimeMillis()
Log.d("AppLog", "it took ${endTime - startTime} ms to convert a single image ($width x $height) to mp4")
}
Когда я пытаюсь работать с несколькими кадрами или даже с двумя кадрами, я вижу, что иногда некоторые кадры пропускаются, что приводит к видео также короче.
Например, в этом сценарии должно быть 2 кадра, каждый из которых занимает 5 секунд, но на выходе получается 5 секунд вместо 10 секунд, и он игнорирует весь второй кадр:
Код: Выделить всё
@WorkerThread
private fun testImages() {
Log.d("AppLog", "testImages")
val startTime = System.currentTimeMillis()
Log.d("AppLog", "start")
val videoFile = File(ContextCompat.getExternalFilesDirs(this, null)[0], "images.mp4")
if (videoFile.exists())
videoFile.delete()
videoFile.parentFile!!.mkdirs()
// Log.d("AppLog", "success creating parent?${videoFile.parentFile.exists()}")
val timeLapseEncoder = TimeLapseEncoder()
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.frame1)
val width = bitmap.width
val height = bitmap.height
timeLapseEncoder.prepareForEncoding(videoFile.absolutePath, width, height)
val delay = 5000
timeLapseEncoder.encodeFrame(bitmap, delay)
val bitmap2 = BitmapFactory.decodeResource(resources, R.drawable.frame2)
timeLapseEncoder.encodeFrame(bitmap2, delay)
timeLapseEncoder.finishEncoding()
val endTime = System.currentTimeMillis()
Log.d("AppLog", "it took ${endTime - startTime} ms to convert a single image ($width x $height) to ${videoFile.absolutePath} ${videoFile.exists()} ${videoFile.length()}")
}
Я пытался просмотреть код и выполнить отладку, но вроде все в порядке...Странно, что если я изменю продолжительность, а также добавлю больше кадров, все будет в порядке, например:
При первом запуске будет создано 12-секундное видео. 6 секунд — это одно изображение, а остальные 6 секунд — другое изображение.
Я также пытался добиться эквивалентности тому, что я сделал изначально, только в большем количестве кадров:
Код: Выделить всё
for (i in 0 until 500)
timeLapseEncoder.encodeFrame(bitmap, 10)
val bitmap2 = BitmapFactory.decodeResource(resources, R.drawable.frame2)
for (i in 0 until 500)
timeLapseEncoder.encodeFrame(bitmap2, 10)
Я думал, что, возможно, это какая-то проблема с fps, но он установлен в коде уже нормально, до 30, что вполне разумно и, вероятно, превышает минимум, разрешенный для формата MP4.
Вопросы
- Что не так с тем, как я это использовал? Почему он пропускает кадры, в результате чего видео становится короче, чем я ожидал?
- Возможно, есть ли лучший способ создания файлов MP4? из изображений, где вы задаете продолжительность каждого кадра подряд? Решение, которое не требует большой библиотеки и не имеет проблемной лицензии?
Подробнее здесь: https://stackoverflow.com/questions/785 ... vide-to-it