JSON-OBJECT Software Engineering Blog

Professional Senior Backend Engineer. Specializing in high volume traffic and distributed processing with Kotlin and Spring Boot as core technologies.

View on GitHub
26 October 2023

Kotlin, Amazon Elastic Transcoder로 원본 동영상에서 오디오만 추출하기

by Taehyeong Lee

개요

build.gradle.kts

dependencies {    
    implementation("software.amazon.awssdk:elastictranscoder:2.21.37")
}

ElasticTranscoderClient 생성

val transcoderClient = ElasticTranscoderClient
    .builder()
    // 대한민국에서 가장 가까운 도쿄 리전으로 설정
    .region(Region.AP_NORTHEAST_1)
    .build()

시스템 프리셋 목록 조회

// 현재 사용 가능한 프리셋 목록을 조회
transcoderClient.listPresets().presets().forEach {
    // Id=1351620000001-100141, Arn=arn:aws:elastictranscoder:ap-northeast-1:776875668468:preset/1351620000001-100141, Name=System preset: Audio AAC - 64k, Description=System preset: Audio AAC - 64 kilobits/second, Container=mp4, Audio=AudioParameters(Codec=AAC, SampleRate=44100, BitRate=64, Channels=1, CodecOptions=AudioCodecOptions(Profile=auto)), Type=System
    println("$it")
}
Id=1351620000001-100110, Arn=arn:aws:elastictranscoder:ap-northeast-1:776875668468:preset/1351620000001-100110, Name=System preset: Audio AAC - 256k, Description=System preset: Audio AAC - 256 kilobits/second, Container=mp4, Audio=AudioParameters(Codec=AAC, SampleRate=44100, BitRate=256, Channels=2, CodecOptions=AudioCodecOptions(Profile=AAC-LC)), Type=System
Id=1351620000001-100120, Arn=arn:aws:elastictranscoder:ap-northeast-1:776875668468:preset/1351620000001-100120, Name=System preset: Audio AAC - 160k, Description=System preset: Audio AAC - 160 kilobits/second, Container=mp4, Audio=AudioParameters(Codec=AAC, SampleRate=44100, BitRate=160, Channels=2, CodecOptions=AudioCodecOptions(Profile=AAC-LC)), Type=System
Id=1351620000001-100130, Arn=arn:aws:elastictranscoder:ap-northeast-1:776875668468:preset/1351620000001-100130, Name=System preset: Audio AAC - 128k, Description=System preset: Audio AAC - 128 kilobits/second, Container=mp4, Audio=AudioParameters(Codec=AAC, SampleRate=44100, BitRate=128, Channels=2, CodecOptions=AudioCodecOptions(Profile=AAC-LC)), Type=System
Id=1351620000001-100141, Arn=arn:aws:elastictranscoder:ap-northeast-1:776875668468:preset/1351620000001-100141, Name=System preset: Audio AAC - 64k, Description=System preset: Audio AAC - 64 kilobits/second, Container=mp4, Audio=AudioParameters(Codec=AAC, SampleRate=44100, BitRate=64, Channels=1, CodecOptions=AudioCodecOptions(Profile=auto)), Type=System

트랜스코딩 Job 요청 및 결과 확인

// 트랜스코딩을 요청할 파이프라인 ID
val pipelineId = "{elastic-transcoder-pipeline-id}"

// 원본 파일의 S3 Key를 지정
// S3 Bucket은 파이프라인 생성 시점에 사전 지정
val inputFileKey = "{input-s3-key}"

// 대상 파일의 S3 Key를 지정
// S3 Bucket은 파이프라인 생성 시점에 사전 지정
val outputFileKey = "{output-s3-key}"

// [Audio AAC - 128k] 시스템 프리셋을 지정
val presetId = "1351620000001-100130"

val jobInput = JobInput.builder()
    .key(inputFileKey)
    .aspectRatio("auto")
    .container("auto")
    .frameRate("auto")
    .resolution("auto")
    .build()

val createJobOutput = CreateJobOutput
    .builder()
    .key(outputFileKey)
    .presetId(presetId)
    .build()

val createJobRequest = CreateJobRequest
    .builder()
    .pipelineId(pipelineId)
    .input(jobInput)
    .output(createJobOutput)
    .build()

// 트랜스코딩 Job을 파이프라인에 요청
val createJobResponse = transcoderClient.createJob(createJobRequest)
ResourceNotFoundException: The specified preset was not found: account={account}, presetId={preset-id}
repeat((1..1000).count()) {

    // 10초마다 트랜스코딩 Job 처리 결과 확인
    // JVM 19 이상에서는 Virtual Thread를 사용
    Thread.sleep(1000 * 10)

    val readJobResponse = transcoderClient
        .readJob(
        	ReadJobRequest
        	    .builder()
        	    .id(createJobResponse.job().id())
        	    .build()
        )

    when (readJobResponse.job().status().uppercase()) {

    	  // 트랜스코딩 완료 결과를 처리
        "COMPLETE" -> {
            val queuedAt: Instant = Instant.ofEpochMilli(readJobResponse.job().timing().submitTimeMillis())
            val startedAt: Instant = Instant.ofEpochMilli(readJobResponse.job().timing().startTimeMillis())
            val endedAt: Instant = Instant.ofEpochMilli(readJobResponse.job().timing().finishTimeMillis())
            val outputFileSize: Long = readJobResponse.job().output().fileSize()
        }

        // 트랜스코딩 에러 결과를 처리
        "ERROR" -> {}
    }
}
tags: Spring Boot