Before diving into code, I was a Video Director and wore many hats in post-production. Now, I help shape the future of media conversions in the cloud with Cinnafilm's PixelStrings Platform.
My name is Marc Leonard. I am a creative professional and software engineer with a unique background that bridges the media and entertainment industry with software development.
In 2010, I graduated from DeSales University in Center Valley, PA, with a major in Television/Film and a minor in Business. Early in my career, I spent two years as the lead editor of special programming for Reelz Channel. Following that, I freelanced for various online media outlets and brands such as Reddit, Pop Sci, and The Verge. I also worked as a colorist for feature films, short-form content, and dailies.
My career took a turn towards the Outdoor Industry, where I started The Crux Collective, a short-lived outdoor news aggregator, and founded Rove Media, a one-man media consultancy. Through Rove Media, I created videos and materials for brands like L.L.Bean, Outside Online, Patrol USA, and GoPro.
Since 2017, I have been working as a Senior Software Developer at Cinnafilm, contributing to the development of PixelStrings, a cloud-based video processing platform. My role involves designing and developing the API and backend, orchestrating cloud infrastructure, and maintaining a horizontally scalable video transcoding system. I leverage my proficiency in Python, JavaScript, TypeScript, and HTML/CSS, along with frameworks like Flask, Django, and FastAPI, to build robust and maintainable applications.
In addition to my professional work, I am the creator of LineDream, a Python generative art library designed for SVG outputs and originally intended for pen plotter art. I am also developing a media asset management software called Asset Veranda.
I am currently enjoying the fruits of living in Bozeman, Montana where I enjoy skiing, mountain biking, and hiking.
-
2017 - Present
Cinnafilm Inc.
Core backend developer for PixelStrings. PixelStrings is a cloud video conversion platform for studios, broadcasters, independent creators, and post-production facilities -
2023 - Present
Asset Veranda
Developer of Asset Veranda - a media asset management tool for producers and editors. -
2012 - 2019
Video Director & Post Production Specialist
For 7 years I worked as a freelancer for many companies and productions. For a comprehensive overview of my work, please visit this link. -
2012 - 2014
Instructor
Adobe Premiere and Adobe After Effects instructor for the University of New Mexico Continuing Education program. -
2011 - 2013
Reelz Channel
Lead Editor of special programming -
2006 - 2010
DeSales University
Major - Television/Film
Minor - Business
- Languages: Python, JavaScript, TypeScript, HTML/CSS, C++, C# (working knowledge)
- Frameworks: Flask, Django, FastAPI, SQLAlchemy, Pydantic, Pytest, boto3, Angular, Vue, HTMX
- Audio/Video Libraries: MainConcept, SRT, FFmpeg, gstreamer, miniaudio, Blackmagic RAW SDK
- Tools: Terraform, Ansible, Docker, Linux, Nginx, AWS, Azure
- Databases: MySQL, PostgreSQL, SQLite, MongoDB, Redis
-
Calling Objective C from C++
Asset Veranda, the media asset manager I'm working on, uses largely platform-independent code. However, there are some specific functions that need to be called that are platform-specific.
For instance, there is a way to display a file in its native file browser (Finder for macOS or Windows Explorer for Windows). In the case of Windows, this is easy. Include the Windows header file and make a few COM calls. But in the case of macOS, you need to call either their Swift or Objective-C APIs.
Below, I've outlined the simplest way to do this using the CMake build system.
main.cpp
#include <iostream> #include "ApplePlatformOps.h" int main() { // wait for user input std::cout << "Press Enter to continue..." << std::endl; std::string filePath; ASelectFolder(filePath); std::cout << "Selected: " + filePath << std::endl; std::cin.get(); return 0; }
ApplePlatformOps.h
#include
void ASelectFolder(std::string& filePath);
ApplePlatformOps.mm
#include "ApplePlatformOps.h" #include <Cocoa/Cocoa.h> void ASelectFolder(std::string& filePath) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSOpenPanel *openPanel = [NSOpenPanel openPanel]; [openPanel setCanChooseFiles:NO]; [openPanel setCanChooseDirectories:YES]; [openPanel setAllowsMultipleSelection:NO]; NSInteger result = [openPanel runModal]; if (result == NSModalResponseOK) { NSURL *url = [openPanel URL]; NSString *pathString = [url path]; const char *utf8String = [pathString UTF8String]; filePath = std::string(utf8String); } [pool release]; }
CMake file
cmake_minimum_required(VERSION 3.10) project(MyProject) set(CMAKE_CXX_STANDARD 17) # Add the path to the FindCocoa.cmake module set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") # Specify the source files set(SOURCE_FILES main.cpp ) set(HEADER_FILES ) if(APPLE) # Add the platform specific files list(APPEND SOURCE_FILES ApplePlatformOps.mm ApplePlatformOps.h ) # Add the platform specific headers list(APPEND HEADER_FILES ApplePlatformOps.h ) find_library(COCOA_LIBRARY Cocoa) endif() add_executable(MyProject ${SOURCE_FILES} ${HEADER_FILES}) if(APPLE) # Link the necessary libraries target_link_libraries(MyProject ${COCOA_LIBRARY}) endif()
-
There are a lot of opinions (and recommended practices) on how to manage Terraform code between development and production environments. One common approach is to have separate Terraform modules (folders) for each environment. This can be a good approach, but it can also lead to a lot of duplication and potential for drift between the environments. I went down the rabbithole to determine the most ergonomic way to accomplish this.
I found that the lowest common denominators to accomplish this are: - Use the
AWS_PROFILE
environment variable to switch between AWS accounts. - Use theterraform workspace
command to switch between environments (corresponding to the AWS accounts). - If you need to create a jsonoutputs
file, use theAWS_PROFILE
environment variable to prepend the name of the output file.Obviously, you can put these commands in a script to link them together, but these are the main steps. The workflow goes as follows:
- Create a new workspace for each environment.
terraform workspace new dev
terraform workspace new prod
- Set up two AWS profiles in your
~/.aws/credentials
file.dev
prod
- Set the
AWS_PROFILE
environment variable to the desired profile.export AWS_PROFILE=dev
- Switch to the desired workspace.
terraform workspace select ${AWS_PROFILE}
- Apply the Terraform code.
terraform apply
- If you need to create a json
outputs
file, use theAWS_PROFILE
environment variable to prepend the name of the output file.terraform output -json > ${AWS_PROFILE}_outputs.json
Using this approach, there are a few concessions you will need to make, such as: - You will need to remember to set the
AWS_PROFILE
environment variable before running any Terraform commands. - You will need to remember to switch to the correct workspace before running any Terraform commands. - You will need to remember to prepend theAWS_PROFILE
environment variable to the output file name if you need to create a jsonoutputs
file.But, even given those, I found this to be the best way to simultaneously manage Terraform code between development and production environments.
- Create a new workspace for each environment.
-
For posterity, here are the things I read, listened to, and used this past year.
Books
- The Priory Of The Orange Tree
- Never Let Me Go
Podcasts
- Software Defined Talk
- Python Bytes
- Talk Python To Me
- Merge Conflict
Gadgets
- Drawing Tablet
Other
- Woodworking