Hackathon Project: Animated gif transformer

Showing results for 
Search instead for 
Did you mean: 

Hackathon Project: Animated gif transformer

Alfresco Employee
2 0 1,656




We all know that the best way to store cat videos is using Alfresco Content Services, but wouldn't it be great if we could easily convert our libraries of cat videos into animated gifs? With the Community Hackathon there was an opportunity to try this out and investigate integrating ffmpeg with Alfresco.



Getting started


The Hello World Transformer is an example project to help getting started creating transformers. After an initial clone of the project I found that I wasn't able to build it. I followed the instructions in the README as follows:
INFO: I/O exception (jnr.enxio.channels.NativeException) caught when processing request to {}->unix:// Connection reset by peer
Jan 21, 2022 10:20:54 AM org.apache.http.impl.execchain.RetryExec execute
INFO: Retrying request to {}->unix://
[ERROR] DOCKER> Unable to build image [alfresco/alfresco-helloworld-transformer:latest] : Connection reset by peer [Connection reset by peer]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.594 s
[INFO] Finished at: 2022-01-21T10:20:55Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.fabric8:docker-maven-plugin:0.33.0:build (build-image) on project alfresco-helloworld-transformer: Unable to build image [alfresco/alfresco-helloworld-transformer:latest] : Connection reset by peer -> [Help 1]

I didn't get to the bottom of this issue, but instead tried updating the parent project (alfresco-transformation-core) to the latest release (2.5.4). After this I was able to build and start the Docker container, but I instead hit a different error:

2022-01-21 10:25:59.959 ERROR 1 --- [nio-8090-exec-3] o.a.transformer.TransformController : No transforms were able to handle the request

org.alfresco.transform.exceptions.TransformException: No transforms were able to handle the request
Unfortunately this error gives very little information about what is going wrong. It took me quite some time reading the code before I noticed the engine_config.json contained a restriction:
"maxSourceSizeBytes": 50

The text file I was uploading was more than 50 bytes and so the Hello World transformer was not considered to be a suitable route. When uploading a smaller text file then everything worked as expected.

I proceeded to update the documentation and made the following pull request:
Once this was merged then it was pointed out to me that another pull request already addressed the same documentation issue in a different way. It had been created six months earlier and would have definitely saved me some pain:
A couple of conclusions from this phase of my Hackathon. It's really important for us at Alfresco to look out for PRs across all our projects. We are now working in feature teams, so the ownership of projects is distributed, which can easily lead to contributions like this slipping through the cracks.
Secondly this reinforced the importance of helpful log messages. I had the application set to log at trace, but there was nothing explaining why the Hello World transformer was not acceptable. I have raised this ticket for the issue.


Add ffmpeg into Docker


Having got the example project working then I moved on to making ffmpeg available to the project. Many thanks to Jan for his help on this! He has already done some work on a far more functional PoC for transformations with ffmpeg, however, sadly (at time of writing) it cannot handle creation of animated gifs.
The Alfresco Hello World transformer Docker image is based on the alfresco/alfresco-base-java image, which is in turn based on CentOS. This presented a small challenge because ffmpeg isn't available from the default yum repository:
Step 8/13 : RUN yum install -y ffmpeg
---> Running in 122295442cc8
No package ffmpeg available.

However with a bit of fiddling I was able to get this to work - see this commit for details.




Converting text to video with ffmpeg


Once ffmpeg was available to my transformer then I wanted to make the smallest change to start using it. Luckily ffmpeg has the ability to generate videos containing text. This Stack Overflow post gives the following method to generate a video from some text:
ffmpeg -f lavfi -i color=size=320x240:duration=10:rate=25:color=blue -vf "drawtext=fontfile=/path/to/font.ttf:fontsize=30:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:text='Stack Overflow'" output.mp4
It took some experimentation to find how to use a RuntimeExec to call through to ffmpeg, but I was delighted once I got it working. This commit has the full details.


Creating cat gifs with ffmpeg


Once I had a transformer calling through to ffmpeg then it was pretty straightforward to set up the parameters to allow me to convert mp4 files into animated gifs. However I instead ran into an unexpected problem:
Problem: There are no mp4s of cats on the internet
There are plenty of sites advertising cat videos and millions of animated gifs, but in my two minutes of Googling then I couldn't find a single (safe-looking) site to download mp4s from. Again this was a case of "ffmpeg to the rescue". I downloaded a gif from the critically acclaimed site Giphy (using this helpful method) and then converted it into an mp4 using:
ffmpeg -i ~/Downloads/cat.gif ~/Downloads/cat.mp4
Now everything was ready for me to nail the demo by converting it back into a gif with my new transformer! This worked as expected and you can see the final code in the GitHub repository.



Shortcomings and Next Steps


Hello World everywhere
A simple grep of the project reveals that I still have 144 references to "Hello World". Some of these are in package and class names, others are in the UI and the Docker image. If you're creating a transformer from scratch then it might be a good idea to use the helloworld project for inspiration, but to write the code for your project from scratch.


Health probe
The code still contains the old getProbeTestTransform method. I assume this means that my transformer would be considered unavailable by the transform router. I didn't get as far as testing this, which brings me onto my next point...


Put everything together
It would be a more compelling demo if I was able to use the transformer in a real ACS system to perform bulk gif generation in parallel. I ran out of time (finishing the project literally one minute before the demo - which is pretty standard for a Hackathon), and so wasn't able to take this to the next level.




During the hackathon I was able to integrate ffmpeg with the transformer code and use it to convert mp4 files into animated gifs. I was also able to make some small updates in the helloworld transformation project and raise a ticket to improve debug logging. I also learnt quite a bit!