Armakuni Contact us
← All case studies

Twenty-four hours of stream.
About thirty minutes worth keeping.

An ad-intelligence business was keeping whole streams to find the ads inside them. We taught the pipeline to listen for the ads first and keep only those minutes, then moved scraping off a server that never switched off and onto event-driven execution.

Before

A server running all day for a job that ran once or twice.

Whole days of video stored to find each ad.

After
~90%lower infrastructure cost
~95%less video stored
~20 minutesa run, down from 30 to 40

A server running all day for a job that ran once or twice

The business tracks which ads run on streaming TV and what's coming next on the streaming services. Its collector only ran on Windows, so it lived on a Windows server in the cloud, switched on around the clock, for a job that ran once or twice a day. Every hour of real work was paid for many times over.

The data was also typed in by hand. A team entered details into spreadsheets, and the scraping and analysis ran from there. It was slow, and every typo carried through.

Whole days of video stored to find each ad

The bigger cost was the video. Finding the ads in a live stream meant downloading the stream, storing it and comparing it, and every step up in resolution made each of those heavier. Most of what they kept was programming they didn't need. A day of stream holds about half an hour of ads, so nearly everything they stored was the part they would throw away.

The pipeline reads the audio before it touches the video

Audio is far cheaper to process than video, and an ad gives itself away in what it says. So we turned the order around: the pipeline reads the sound, finds where each ad starts and ends, and only then touches the video, to cut out just those minutes.

That one change meant about 30 to 40 minutes are kept from each 24-hour stream instead of the whole day.

How we built it

4 decisions, in the order we made them. Each one says what we did and why, with what it did drawn beside it.

  1. The obvious way was to watch the picture
  2. Fitting a 40-minute job into Lambda's 15 minutes
  3. Deciding where the AI is allowed to be wrong
  4. A list of upcoming originals across every service

The obvious way was to watch the picture

Built withTranscribeBedrock
Finding the ad breaks Listen to the audiochosenWatch the pictureheavier
The engineering

Most ad detection starts with the video, pulling the stream and searching its frames for where the break begins. That means choosing a resolution, and every step up multiplies the data to move, store and compare. Even at the lowest one, a day of stream is still a day of video to handle.

We went to the sound instead. Amazon Transcribe turns the stream's audio into text, and Bedrock-based tagging reads that text and marks each advertising segment with its start and end timestamps. Those timestamps are the cut list. The pipeline extracts the corresponding video and nothing else, so the stream is never kept, or processed end to end, at full resolution.

Why: the video was the expensive part of this pipeline, so the design keeps it out until the last step, and then only for the minutes that matter.

Each clip is then tagged, again with Bedrock: the brand behind the ad, which parent brand that product brand belongs to, and how often the ad runs. Those records are the base of the business's ad database, and they pass through the same confidence line as everything else (below).

Fitting a 40-minute job into Lambda's 15 minutes

Built withLambdaS3SQS
A 30–40 minute job 1234 Done short phases, one after anotherthe bill fell about 90%
The engineering

A job that runs once or twice a day shouldn't need a server at all, because AWS Lambda only bills while code is running. Two things stood in the way. The scraper only ran on Windows, and it ran for 30 to 40 minutes, while a Lambda function stops at 15.

The first was a rewrite into Python, which doesn't care what it runs on. The second was the real design decision. The usual answer to a job that outgrows Lambda is a container that stays up, which would have brought the always-on bill straight back. We cut the job into phases instead, each short enough to finish inside the limit, which made the processing Lambda-based and event-driven.

Each phase writes its intermediate files to Amazon S3 and puts a message on an Amazon SQS FIFO queue, which starts the next phase. FIFO matters here, because a phase must never start on the files of one that hasn't finished. So S3 holds the state and the queue holds the sequence, with no persistent database and no server waiting between runs. The infrastructure bill fell about 90%, and a run now takes about 20 minutes where the old script took 30 to 40.

Deciding where the AI is allowed to be wrong

85% confident or more Straight on A person about 15% go to a person
The engineering

No extraction model is right every time, so the question that matters is what happens when it isn't. Every record the AI produces carries a confidence score. At 85% or above it's marked verified and written to the database. Below 85%, it goes out as a Slack notification for human validation.

That threshold is the decision. Set it lower and mistakes reach the database unseen; set it higher and people spend their day re-checking work the model got right. At 85%, about 15% of records go to a person. The colleague who once typed everything into a spreadsheet now only confirms or corrects those, with a click in the front end the business already had. Each correction goes back to the model, so that share can keep shrinking. The ad metadata follows the same rule: tags at 85% or above go straight into the ad database, and the rest go to a reviewer.

A list of upcoming originals across every service

Built withBedrock
Provider 1Provider 2Provider 3Provider 4 One list
The engineering

Every streaming service publishes its own release list. Nobody publishes the list the business needed: the upcoming originals across all of them, meaning the shows one service makes to run only on that service. Third-party sources had the data, spread across four providers, each unstructured, inconsistent and overlapping with the others.

We scrape all four and normalize what comes back, then hand a model on Bedrock the part that rules handle badly: deciding that two differently written entries are the same show. The pipeline merges them, and the output is one clean, deduplicated list of upcoming originals.

One day in the pipeline

Put together, a day of one stream runs like this:

  1. Amazon Transcribe turns the stream's audio into text, and the video is left alone for now.
  2. The ads are found in the text. Bedrock-based tagging returns each advertising segment's start and end timestamps.
  3. Only those minutes are cut. The pipeline extracts the matching video, about 30 to 40 minutes out of 24 hours, and the rest is never stored.
  4. Each clip is described. Bedrock tags the brand, its parent brand and how often the ad runs.
  5. The confidence line decides who sees it. At 85% or above the record is verified and goes into the ad database. Below that, a Slack notification asks a person to confirm or correct it, and the correction goes back to the model.
  6. Collection runs in phases. Lambda functions short enough for the 15-minute limit hand over through files in Amazon S3 and messages on an Amazon SQS FIFO queue. Nothing runs between collections, and nothing is billed while it waits.

What we'd tell another CTO

1Find the cheapest signal that answers the question and touch the expensive data last. Here the sound told us where the ads were, so the video only had to be cut, never searched.
2Treat a runtime limit as a design input. Lambda's 15-minute limit forced the phases, and the phases gave the business a pipeline with no idle cost.
3Decide where the AI is allowed to be wrong before choosing the model. The 85% line, and the person behind it, is what made the output safe to put in a database, and the rest belongs in plain code: deciding that two release entries are the same show is a judgment, while scraping, normalizing and merging aren't.

What else changed

  • About 15% of records still go to a person, to check rather than type.
  • One deduplicated list of upcoming originals from four sources.

What comes next

The next phase is designed and scoped, and it follows the same principle of never capturing anything twice. Each live stream gets a unique audio fingerprint, sent to the business's existing Amazon MSK (Managed Streaming for Apache Kafka) stream for downstream processing. When a new stream has the same channel and market identifiers as one already running, the system reuses the active stream, which avoids redundant capture and is designed to cut subscription and bandwidth costs. The plan covers 10 channels in each of the 210 U.S. TV markets, streamed live from YouTube, and fingerprints for upcoming originals from 10 streaming services in five countries, in English and German.

How we'd do it today

This project came before our current offers. Here's how we'd approach the same work now.

The 85% line would come out of evals: a golden set of real past streams with every ad break marked by the business's own people, plus a sealed set no prompt writer sees, with each candidate threshold scored on the mistakes it lets through and the correct records it sends to a person, so the business picks the trade it wants. The brand hierarchy would become a domain model the business's experts sign off, because parent and product brands are business decisions a model shouldn't guess.

At 10 channels in each of 210 markets, tagging cost grows with every stream, so Agent ControlPlane, part of AK Run, would make Amazon Bedrock AgentCore Gateway the only way to a model, recording each call with the model, its trigger and its cost, while AWS Service Control Policies refuse any model that isn't approved. A new prompt or model would reach a small share of streams first and roll back on its own if accuracy, speed or errors cross an agreed line, and overnight AI agents would try changes that send fewer records to people, with only those that fail nothing sealed going to the team to approve.

Where the bill is the model itself, AI Inference Engineering would move the routine tagging calls to a model the business owns on Amazon SageMaker AI, at about a tenth of the price, with the hard ones on a frontier model through Amazon Bedrock, and the model, its tests and the data in the business's own AWS account.

Have a problem like this one?

A free workshop: a few hours with the architects who'd do the work, on your own systems. No cost.

Book a free workshop