No one can imagine today’s life without video. It became the main source of information. The information transferred through video is the most easily digestible. Now you can watch video everywhere and on every device. Video consumers become more spoiled and expect higher quality and faster services e.g. streaming. Nobody wants their content interrupted because of video buffering, skipped frames or the dreaded crashed players. So, that’s why it is very important that video is of equally high quality on all possible devices. This can be easily integrated with the help of AWS Elastic Transcoder. Let’s have a look at it.
What is transcoding?
Transcoding is a process of reformatting video from one codec/format into another. It is a very important part of online video broadcasting as it makes sure that all videos can be viewed on all users’ devices. It is used to convert all three elements of a digital video at the same time – the file format, the video, and the audio.
Why every business has to have a transcoder
Some source files are usually made with high-quality tools and programs, so the end users can not play the video on their device.
The source file is usually larger than the asset file. So, it will take longer to download.
The source files must comply with some encoding rules in order to make all Adaptive Bitrate mode(ABR) functionality to work properly. For example, the key frames in all ABR assets must be aligned to the same timing. Transcoding does it automatically.
Most video producers usually are not eager to generate all those assets by themselves, which is another reason for having transcoding done automatically as part of video processing.
There are two ways of implementing transcoding:
- Hard one
- And easy one
So hard one is to have your own transcoding software for ex FFMPEG residing on some server and waiting for videos to be uploaded. Once a video is uploaded it is to convert it to every format you need. As a matter of fact, to assemble all formats and codecs is a pain in the neck.
Luckily, there is a very easy and convenient way to follow. AWS has video transcoding service which is totally serverless and could be launched separately.
So video transcoder will do the following:
- 1. Get video file
[code language=”groovy”]
MultipartRequest multipartRequest = request as MultipartRequest
if (multipartRequest && multipartRequest.getClass().name.contains(‘MultipartHttpServletRequest’)) { MultipartFile attachmentFile = multipartRequest.getFile("filename")
String contentType = getServletContext().getMimeType(attachmentFile.getOriginalFilename());
String filename = FilenameUtils.getBaseName(attachmentFile.getOriginalFilename())
//define file path on server and it’s matching path in the bucket
String filepath = "YourFilePath"
File fileToProcess = new File(filepath)
attachmentFile.transferTo(fileToProcess)
[/code] - Upload to s3 destination
[code language=”groovy”]
ObjectMetadata objectMetadata = new ObjectMetadata()
objectMetadata.contentType = contentType
Long contentLength = Long.valueOf(new File(filePath).size());
objectMetadata.setContentLength(contentLength);
amazonWebService.s3.putObject(new PutObjectRequest(bucketName, filePath,
new File(filePath).newInputStream(), objectMetadata)
.withCannedAcl(acl))
[/code] - Start transcoding process
[code language=”groovy”]
public CreateJobResult createQueue(String filePath, def params) {
AmazonElasticTranscoder elasticTranscoder = amazonWebService.getElasticTranscoder()
List<String> presets = getPresetsFromConfig(params)
JobInput input = new JobInput()
input.setKey(filePath)
input.setAspectRatio("auto")
input.setContainer("auto")
input.setFrameRate("auto")
input.setInterlaced("auto")
input.setResolution("auto")
CreateJobRequest createJobRequest = new CreateJobRequest()
createJobRequest.setPipelineId(pipelineId)
createJobRequest.setInput(input)
createJobRequest.setOutputKeyPrefix(outputPrefix + ‘/’)
Collection<CreateJobPlaylist> playlists = []
List<CreateJobOutput> outputs = new ArrayList<CreateJobOutput>()
presets.each { String presetId ->
CreateJobOutput output = new CreateJobOutput()
ReadPresetResult readPresetResult = getReadPresetResult(elasticTranscoder, presetId)
String outputKey = "${filePath}-${readPresetResult.preset.name}.${readPresetResult.preset.container}"
if (readPresetResult.preset) {
if ([‘ts’, ‘fmp4′].contains(readPresetResult.preset.container)) {
playlistFormats.each { String playlistFormat ->
if (checkPlaylistFormatForPreset(readPresetResult.preset.container, playlistFormat, params)) {
CreateJobPlaylist createJobPlaylist = new CreateJobPlaylist()
createJobPlaylist.setName("${filePath}-${playlistFormat}")
createJobPlaylist.setOutputKeys([outputKey])
createJobPlaylist.setFormat(playlistFormat)
playlists.add(createJobPlaylist)
}
}
output.setSegmentDuration(’10’)
} else if (readPresetResult.preset.thumbnails) {
output.setThumbnailPattern("${filePath}-${readPresetResult.preset.name}-{count}")
}
output.setKey(outputKey)
output.setPresetId(readPresetResult.preset.id)
output.setRotate("auto")
outputs.add(output)
}
}
createJobRequest.setPlaylists(playlists)
createJobRequest.setOutputs(outputs)CreateJobResult createJobResult = elasticTranscoder.createJob(createJobRequest)
Job job = createJobResult.getJob()
markStorageDirJobIsCreated(‘REQUESTED’, job.id, filePath)
return createJobResult
[/code]
When transcoding work is completed, do whatever has to be done in context of your application. For example, mark that video files as available for users.
Depending on a file size it could be a simple serverless application with help of Lambda functions. Lambda function will upload the file and start transcoding process or start next Lambda function. If the file is massive we could have some server app running and waiting for an upload. Once the application has saved the video file on s3 it starts transcoding job and waits for SNS events to notify that conversion has been finished. Admitting transcoding itself is a relatively quick operation.
In the end, we have the video file converted to a range of different formats. Now your web content is ready to be consumed by all known devices without delay.