Published in


Blog | Creating Video “Stories”

Apps like Snapchat and Instagram have “video stories” where the videos are visible for 24 hours, and then disappear. Stories are a great way to keep engagement, and have users regularly check in (so they do not miss a story).

In this post, we’ll walk through a demo application that mimics the “story” framework. You’ll see how you can easily implement a feature like stories with api.video.


We’ve build a demo application at storyify.a.video that will display videos that fit our “Story” parameters.

To start, we need to identify the videos we want to appear in our story timeline. In your app, you’d probably ID this by a username or groupname, either from your dyanamic metadata or perhaps with a .

In the demo app, I have 3 groups of videos that will appear:

In practice, you’re most likely to use a tagging method to sort your stories. However, we don’t publish a new tutorial video daily, so it does not work well with the demo (on the other hand, the livestreams almost always have one or more video saved a day).

You can also set the period for the story. Like Instagram and Snapchat, we’ve set this value to 24 hours.

Determining the videos to display

On submittal of this form, the data appears on the NodeJS backend. This code is available on

var currentTime = new Date(); //get the values from the form to figure out which stream, and for how far backwards if(req.query.hours){ hours = req.query.hours; } if(req.query.chooseStory){ videoStream = req.query.chooseStory; } //we need to convert hours to ms, 3600s in an hour, 1000ms in a sec var hoursInMs = hours*3600*1000 var earliestTime = new Date(currentTime - hoursInMs);

First we retrieve the current time on the server (currentTime). We then extract the number of hours, and the story chosen from the form.

Since time is measured in ms since 1970, we convert the hours our story will stay live to milliseconds, and then do a difference from the currentTime to find the beginning time for our story timeframe.

Search for videos

Now we can search for videos that fit these parameters. Our backend is Node, so we can use the NodeJS video search. We’ll modify the search parameters based on the story type selected by the user on the form

const client = new apiVideo.Client({ apiKey: apiVideoKey }); if (videoStream==="piLivestream"){ // pi livestream saved videos searchParameters = {currentPage: 1, pageSize: 25, sortBy: 'publishedAt', sortOrder: 'desc', liveStreamId: 'liEJzHaTzuWTSWilgL0MSJ9'}; } else if (videoStream==="foreheads"){ // livestream a video saved videos //"foreheads" is a joke - most of the thumbnails are of someone's forehead searchParameters = {currentPage: 1, pageSize: 25, sortBy: 'publishedAt', sortOrder: 'desc', liveStreamId: 'li400mYKSgQ6xs7taUeSaEKr'}; }else if (videoStream==="tutorials"){ //these are video tutorials for a.video //tagged 'avideo' searchParameters= {currentPage: 1, pageSize: 25, sortBy: 'publishedAt', sortOrder: 'desc', tags: ['avideo']}; }

The search parameters is a JSON list of the parameters to search over: 1. We cannot search by timeframe, so I am making a guess that there will not be over 25 stories in the timeframe. 2. Videos are sorted by publishedAt, with newest videos first. 3. we use either the liveStreamId, or tags attribute to refine the videos to the ones we want.

Now we are ready to make our query:

let result =client.videos.search(searchParameters); result.then(function(videoList){ //25 most recent stories console.log(videoList); //let's get the ones that fit inside the "story lifetime" var validStories=[]; for (var i=0;i<videoList.length;i++){ var publishDate = new Date(videoList[i].publishedAt); //console.log("published", publishDate); if(publishDate > earliestTime){ //any videos that match this are valid to display //grab the title and the iframe url console.log("published", publishDate); var iframe = "iframe src=\""+videoList[i].assets.player+"\" width=\"50%\" height=\"25%\" frameborder=\"0\" scrolling=\"no\" allowfullscreen=\true\""; var name = videoList[i].title; var data = { "name": name, "iframe":iframe, "published":publishDate }; validStories.push(data); } } //ow we have all the videos //send them to the webpage console.log(validStories); return res.render('story', {hours, validStories}); }).catch((err) => { console.log(err); });

The videoList array will have the most recent 25 videos that fit our filters. We can then loop through this list, and only look for videos where the publishedAt date is greater than the earliestTime (the earliest allowed story).

For all videos that meet the story timeline criteria, we create an iframe to display the video, the created time and the title of the video. We return this array to the webpage, where the videos are listed (with their name and created date.

Here is a screenshot from my park livestream “stories”

In the last 24 hours, there were 9 videos posted to the park livestream.


The idea of videos that “expire” after a certain amount of time, much like video stories in Instagram or Snapchat, can easily be enabled in your api.video based application. Using the example at storyify.a.video , and the sample code on , can help you get started with your video story plan.

Have you implemented something similar? Drop a link in our community forum . We’ve love to see what you came up with, and if you had any challenges.

Originally published at https://api.video.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store