운영하는 서비스 개발 중 URI를 통한 영상/비디오의 Thumbnail(썸네일)을 추출하여 준비시켜놓아야 했기에 MediaMetaDataRetriever를 통해 썸네일 추출 방법을 찾아보고 적용해보았다.
구글 공식 문서에서는 'MediaMetadataRetriever 클래스는 입력 된 미디어 파일로부터 프레임 메타 데이터를 검색하기위한 통일 된 인터페이스를 제공한다.'라고 설명하고 있다.
미디어 파일에는 영상 혹은 이미지의 사이즈, 크기, 회전 여부 등 다양한 MetaData가 내재되어 있는데, MediaMetaDataRetriever는 이러한 정보를 꺼내주는 역할을 하는 것이다.
실제로, 운영중인 서비스에서 영상의 길이, bitrate, 사이즈 등을 확인하기 위해 MediaMetaDataRetriever를 사용하였다.
백문이 불여일견이라고 바로 코드를 확인해보자
class VideoThumbnailUtil {
//영상의 1초 시간의 사진을 가져옴
val thumbnailTime = 1
fun getWebVideoThumbnail(uri : Uri) : Bitmap? {
val retriever = MediaMetadataRetriever()
try {
retriever.setDataSource(uri.toString(), HashMap<String,String>())
return retriever.getFrameAtTime((thumbnailTime * 1000000).toLong(), MediaMetadataRetriever.OPTION_CLOSEST)
} catch (e : IllegalArgumentException){
e.printStackTrace()
} catch (e : RuntimeException){
e.printStackTrace()
} finally {
try {
retriever.release()
} catch (e : RuntimeException){
e.printStackTrace()
}
}
return null
}
}
영상 추출을 위해 우선 MediaMetadataRetriever(val retriever)를 생성해주고, retriever에 추출할 영상의 URI을 담아준다.
그 후 retriever에 getFrameAtTime을 사용하여 원하는 부분의 마이크로세컨드(백만분의 1초, 10^-6)를 지정하면 원하는 부분의 Bitmap을 얻을 수 있다.
한편, 비디오 썸네일 추출은 당연하게도 작업 시간이 걸리기 때문에 많은 양을 Main Thread에서 작업할 경우 화면이 멈추거나 느려지는 현상을 겪을 수 있다. 그렇기 때문에 여러 영상의 썸네일을 추출하기 위해선 Background Thread에서 작업하도록 제어해야한다.
videoThumbnailDisposable = Observable.just("${영상 url}")
.subscribeOn(Schedulers.io())
.subscribe {
binding.ivVideoThumbnail.load(
VideoThumbnailUtil().getWebVideoThumbnail(Uri.parse("${영상 url}"))}
RX Kotlin으로 Background Thread(Schedulers.io())에서 binding.ivVideoThumbnail이라는 ImageView에 Coil 라이브러리를 활용하여 결과물인 bitmap을 담아주었다.
좋은 글 감사합니다!! 질문좀 드리고 싶은데 가능할까요?.?ㅜㅜ