Build Social Media Style Stories with Android and Python

Instagram has a popular feature, which is called Stories, inspired heavily by Snapchat. Stories enable users to create a video or a still picture that will disappear in a short period (24 hours). Later, other social media platforms developed this feature as well, such as Linkedin and Twitter.

In this tutorial, we will build this feature for Android with Vonage’s Video API, we’ll also need a server to handle the sessions and tokens for the client, which will be built using Python.

Prerequisites

Building the Server

To begin, we’ll be building a server that our mobile application can communicate with. This server will be using Django, a Python web framework.

Installing Dependencies

First, create a Python virtual environment by running the following two commands:

https://medium.com/media/fefb6298bdba42c442f35c24e58db785/href

Then we can install dependencies for our backend server:

https://medium.com/media/65f1dabcf6c6a46d73735bda17a64a28/href

The command above will install Django, and Opentok the Vonage Video Python SDK.

Creating a Project and an Application

Initialize your Django project by running the following command:

https://medium.com/media/4317d659e9f542bdba46fae3bd1727dd/href

Before we jump into writing the code, we need to create at least one application inside the Django project. A Django project can consist of many applications. For example, project A can be a Stories application, while project B could be a messaging application or e-commerce application. First, change your current directory into the project directory and then initialize a new application with the two commands shown below:

https://medium.com/media/3c669c06c718b1fb6eb6635781d1e53b/href

You don’t have to execute the next command because we won’t be using a database in this tutorial. However, a warning will persist unless we execute the migration command, so run the following to stop these warnings.

https://medium.com/media/c5c6bd6c1e17119aec08ef343dac3a72/href

To make sure our Django web application works, you can run the webserver script.

https://medium.com/media/65579e23d2a65591c0744bb16fd0e579/href

You can access your web application at localhost with port 8000. Which, in your browser will look like http://localhost:8000. If you go to this URL, you’ll be greeted with a success message and a picture of a rocket.

Environment Variables

Our code will need to use your Vonage Video (also known as OpenTok) API key and secret, which should never be hardcoded into your application. To increase the security of the application, you can use environment variables. In your Terminal, you can set your two values as shown in the examples below. Make sure to replace xxxxxx with your values. You can get these values for the API key and API secret in the Vonage Video API docs.

https://medium.com/media/cbe4a7de99377814f555a2c3c960928d/href

Create the Views

Views are the templates that are rendered in your Django application. Open the storiesserver/storiesapp/views.py file and replace the contents of it with the following:

https://medium.com/media/8c7b923566f24f478c59c6348b603c73/href

The first part of this code creates an OpenTok instance, which will use our pre-set environment variables for the API key and API secret.

Then we have two global variables, videos and index. They are like a mini database in memory that holds our stories (or videos) information.

In the first method, we generate our session and token with the get_token method. To create a session, we use the create_session method from the OpenTok instance. It accepts two parameters: a media mode and an archive mode. We use the MediaModes.routed value for media mode because we publish a video as a Story, not for video chatting. MediaModes.routed means we send the video to the server instead of another client. We use the ArchiveModes.manual value for archive mode because we want to archive (record) the video manually so we can get the archive id. This id is important when we want to get the recording video. If not, we have to iterate it from the archive list which is inconvenient. To generate the token, we use the generate_token method from the session instance. We pass the expired time value as a parameter inside this method. Then, in the end, we send the session, the token and the API key to the client.

In the second method, the video_stream method, we get the video URL from the archive id. If you notice, this method has an additional parameter besides the usual parameter, request. How we get the archive id is done in another method.

In the third method, the videos_list method, we send the list of our videos to the client. It is basically our videos variable wrapped in JSON.

In the fourth method, the video_start_archive method, we archive the video. This method has an additional parameter, session_id. We use the start_archive method from the OpenTok instance. It accepts an OpenTok session. After executing this method, our video session will be recorded. The start_archive method returns the archive id. We store it to the videos variable. Other than the archive id, we generate a nice name for this video which is something like “Story 1”, “Story 2”, and so on.

The last method, the homepage method, is just for testing purpose to verify whether the Django web application can be accessed or not.

Create URLs Mapping

Then we need to create a mapping from URLs to these views methods. Create the storiesserver/storiesapp/urls.py file and copy the example below into the file:

https://medium.com/media/8bb21df979a2491f9cdeba82ea36351a/href

The path method accepts three arguments:

URL path The method to be accessed A name for the route for reference purposes.

For example, the second path maps the token URL to the get_token method in the views.

On the server-side of the Django application, we need to modify the urls.py file to map to the stories URLs, so locate the file: storiesserver/storiesserver/urls.py and replace the contents of this file with:

https://medium.com/media/ea615ba1741cb498cb0d5fdb600c80a7/href

Ngrok

To expose the Django application to the Internet and our Android devices during development, we will be using Ngrok. After connecting your account, we can start an HTTP tunnel which forwards to our Django web application port, 8000:

https://medium.com/media/5f8fcd4feae4a9622f0e914878653864/href

When the tunnel has been created, you will see the public URL which looks something like: https://xxxxxxxx.ngrok.io. Then you need to modify the storiesserver/storiesserver/settings.py file, by adding the “xxxxxxxx.ngrok.io”, “10.0.2.2” and “localhost” strings to the ALLOWED_HOSTS variable. The 10.0.2.2 address is the way the Android emulator access localhost in your computer.

Your ALLOWED_HOSTS variable should look like this after the alteration:

https://medium.com/media/a595b4d681fb712e5f2fc3e71d129888/href

Then to access the token URL, you would access this URL: https://xxxxxxxx.ngrok.io/stories/token.

At this point, you have built the server component which can generate tokens, archive video recording and deliver video recording URL. Next, you are going to build an Android application that acts as a client to this server application. With this mobile application, you can record videos and watch the video recordings.

Client Side

Fire up Android Studio, create a new project and select “Empty Activity” for your project template. For the minimum SDK, choose “API 16: Android 4.1 (Jelly Bean)” and for the language, choose “Kotlin”.

https://medium.com/media/73b76383ce4cac01c6dd2ab38ceba191/href

Dependencies

The first thing needed when building a project in Android Studio is to add any dependencies needed. Open the build.gradle in project level and add the following line inside the repositories block which is located inside the allprojects block. Then sync the file.

https://medium.com/media/a18128bcf2bf95bf89751b82e1d3cf5e/href

The second thing you have to do is to add dependencies on the file, which has the same name build.gradle but in application level (or module level). Add these lines inside the dependencies block. Do not forget to sync the file.

https://medium.com/media/40d01cea6bf57ff66af351d63bf5e46d/href

This project uses five additional libraries, these are:

Vonage Video SDK (OpenTok) OkHttp library to send requests to our backend server, Gson library to parse JSON response, EasyPermissions library to handle permissions when our Android application asks permissions to use camera and microphone, Coroutines library to handle non-blocking and blocking code conveniently.

Network Security Config

This step is optional. If you want to test the application with an emulator and do not want to use Ngrok, then you need to create a network configuration file. Create the xml directory inside the res directory, then create a new file called network_security_config.xml file inside the xml directory. Copy the following into it:

https://medium.com/media/18fa37269fc42b1a93c4a6e9d1d8266f/href

It means you can develop the application without the HTTPS protocol for the backend URL.

Android Manifest

To activate this network configuration, open the AndroidManifest.xml file and add the following attribute into application node:

https://medium.com/media/8b046d2845e3ee25d812dcb0a0441252/href

Then add the following inside the manifest node.

https://medium.com/media/9e6ced33bbcb13c0e524079d64546f13/href

We need these two additions because we want to connect our mobile application to our backend server.

While we’re in this file, let’s create references to an additional two activities which will be created later. Add these lines after the only activity node.

https://medium.com/media/791460940c290085a57d50fc9fa57337/href

Layout

We have three Activities, but we need to create 3 layouts for these Activities. We also need to create an additional layout for row layout in a RecyclerView used within the MainActivity.

First, create the row layout by creating a new file named row.xml within the app/src/main/res/layout directory. Copy the following XML into this new file:

https://medium.com/media/6030cfb72a01131ca17f53eea674560d/href

The above defines the creation of a button, which will be used to launch an Activity to watch the story or the video.

Next, we need to create a layout to display a Video. Create a new file named activity_viewing_story.xml in the layout directory, and add the following XML to the file:

https://medium.com/media/9acddec2a0af3a88872a4267c239b8c3/href

The layout contains a WebView which will render the video.

Next, we have to create the activity_creating_story.xml file. This is the layout used by the Activity to create a video. Delete the content of the file and add the following code to it:

https://medium.com/media/d3542687f46270b9ee1c34288b20b665/href

The FrameLayout with the publisher ID is used by the Video SDK to display the video which is being sent to the Video server. The purpose of the button in this Activity is to stop the recording of the video and end the Activity.

Lastly, we need to edit the activity_main.xml file. This file contains the layout used by the MainActivity, which will list all stories (videos) that have been created. The file will also contain a button to launch the Activity to create a video. Replace the contents of this file with the following XML to it:

https://medium.com/media/a0d4de0455b51ea512af4c98b02ae4dd/href

Adding Server URL

Let’s define the server URL within the strings.xml file which can be found in the values directory. Do this by adding the following to your resources node:

https://medium.com/media/92fb34dcefe25429338f59b2b3294f9d/href

If you are using Ngrok though, change it to the following example (make sure to replace xxxxx with your ngrok URL):

https://medium.com/media/14e69631e59fb0323383c6d38da2efdf/href

Classes and Activities

First, we’ll need to create the necessary classes for a RecyclerView. A RecyclerView needs an adapter and a holder. Create a holder file by creating the file with the name StoryViewHolder.kt within the package directory. The package will be something similar to com.example.storiesapplication which is located inside the java directory. Copy the following code into this new file:

https://medium.com/media/11297a14d92d955620869100c9add62e/href

For every class or Activity file you create, make sure you change the com.example.storiesapplication package to your package if your package is different.

This is a standard holder class where you set the text of the button with a string parameter and set a callback for the button.

After creating the holder class, we need an adapter class. An adapter is a bridge between data and the view of RecyclerView. Create a new file within the java/package/ directory called StoryAdapter.kt file and add the following code in this file:

https://medium.com/media/f7aa767bd635a1e5606915dc980fbe94/href

The onCreateViewHolder method inflates the row layout and creates an instance of the holder class. The onBindViewHolder method sets the data to a specific row of the RecyclerView, and the getItemCount method returns the number of items stored.

It’s now time to create the RecyclerView in the MainActivity. Modify the MainActivity.kt file, by replacing the contents with the following:

https://medium.com/media/bb23a7d723d6d48e7d3cbf44744da583/href

The onCreate method adds a callback to the floating button in this Activity, which will call the getToken method to get the token, the session, and the API key before passing them to the CreatingStoryActivity Activity. The RecyclerView also loads the video list, and for each row, we add a callback to call the ViewingStoryActivity Activity.

https://medium.com/media/41ad1808c553a29e879dfb4ecd575184/href

In the onCreate method above, we request permissions for the camera, internet, and audio recording. If we have the permissions, we create a session object using the token, the session, and the API key. We also have to set the listener for this session object. We also set a callback to the button in this Activity. The button will send a request to stop archiving the video.

We have many methods required by the session listener. The most important one is the onConnected method, which will be called if our session has connected to the OpenTok server.

We create a publisher object and set the FrameLayout as the publisher’s view. We also have to connect our session object to this publisher object. Then we create a request object to start archiving the video.

https://medium.com/media/e7cc094ab388ab0ae3411a4852e34add/href

At first, we get the video URL from the archive id by sending a request to our Django application. Then we load the URL in the WebView.

Launching the Application

Launch the application. Remember to use Ngrok or deploy the Django application on the cloud if you want to use an Android device. At first, you will see an empty screen and a floating button.

Press the floating button and the device will stream a video from your camera to the OpenTok server. When you have recorded enough for your story, press the “Upload Story” button on the screen.

You will be redirected back to the main screen, that now displays a list of your stories.

If you press the story row, you will be redirected to the viewing story screen. You can watch your video that you have recorded previously.

Conclusion

This application is far from perfect. If you notice, the recorded video is shorter than the recording session. That happens because it takes time to send a request to archive the video. On top of that, our stories list is a simple RecyclerView. You can convert them to a horizontal scroll. Each story is wrapped in a circle shape just like Instagram Stories looks like! We also do not have authentication and authorization. There is no owner for the story. This video is stored in the OpenTok server for some time. After that, the video will be deleted. You can choose to save the video somewhere else before that happens.

Resources

  • Check out our documentation for the Vonage Video Api here
  • The code for this blog post is on GitHub

Originally published at https://learn.vonage.com/blog/2021/03/23/build-social-media-style-stories-with-android-and-python/


Build Social Media Style Stories with Android and Python was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Vonage Dev

Instagram has a popular feature, which is called Stories, inspired heavily by Snapchat. Stories enable users to create a video or a still picture that will disappear in a short period (24 hours). Later, other social media platforms developed this feature as well, such as Linkedin and Twitter.

In this tutorial, we will build this feature for Android with Vonage’s Video API, we’ll also need a server to handle the sessions and tokens for the client, which will be built using Python.

Prerequisites

Building the Server

To begin, we’ll be building a server that our mobile application can communicate with. This server will be using Django, a Python web framework.

Installing Dependencies

First, create a Python virtual environment by running the following two commands:

Then we can install dependencies for our backend server:

The command above will install Django, and Opentok the Vonage Video Python SDK.

Creating a Project and an Application

Initialize your Django project by running the following command:

Before we jump into writing the code, we need to create at least one application inside the Django project. A Django project can consist of many applications. For example, project A can be a Stories application, while project B could be a messaging application or e-commerce application. First, change your current directory into the project directory and then initialize a new application with the two commands shown below:

You don’t have to execute the next command because we won’t be using a database in this tutorial. However, a warning will persist unless we execute the migration command, so run the following to stop these warnings.

To make sure our Django web application works, you can run the webserver script.

You can access your web application at localhost with port 8000. Which, in your browser will look like http://localhost:8000. If you go to this URL, you'll be greeted with a success message and a picture of a rocket.

Environment Variables

Our code will need to use your Vonage Video (also known as OpenTok) API key and secret, which should never be hardcoded into your application. To increase the security of the application, you can use environment variables. In your Terminal, you can set your two values as shown in the examples below. Make sure to replace xxxxxx with your values. You can get these values for the API key and API secret in the Vonage Video API docs.

Create the Views

Views are the templates that are rendered in your Django application. Open the storiesserver/storiesapp/views.py file and replace the contents of it with the following:

The first part of this code creates an OpenTok instance, which will use our pre-set environment variables for the API key and API secret.

Then we have two global variables, videos and index. They are like a mini database in memory that holds our stories (or videos) information.

In the first method, we generate our session and token with the get_token method. To create a session, we use the create_session method from the OpenTok instance. It accepts two parameters: a media mode and an archive mode. We use the MediaModes.routed value for media mode because we publish a video as a Story, not for video chatting. MediaModes.routed means we send the video to the server instead of another client. We use the ArchiveModes.manual value for archive mode because we want to archive (record) the video manually so we can get the archive id. This id is important when we want to get the recording video. If not, we have to iterate it from the archive list which is inconvenient. To generate the token, we use the generate_token method from the session instance. We pass the expired time value as a parameter inside this method. Then, in the end, we send the session, the token and the API key to the client.

In the second method, the video_stream method, we get the video URL from the archive id. If you notice, this method has an additional parameter besides the usual parameter, request. How we get the archive id is done in another method.

In the third method, the videos_list method, we send the list of our videos to the client. It is basically our videos variable wrapped in JSON.

In the fourth method, the video_start_archive method, we archive the video. This method has an additional parameter, session_id. We use the start_archive method from the OpenTok instance. It accepts an OpenTok session. After executing this method, our video session will be recorded. The start_archive method returns the archive id. We store it to the videos variable. Other than the archive id, we generate a nice name for this video which is something like "Story 1", "Story 2", and so on.

The last method, the homepage method, is just for testing purpose to verify whether the Django web application can be accessed or not.

Create URLs Mapping

Then we need to create a mapping from URLs to these views methods. Create the storiesserver/storiesapp/urls.py file and copy the example below into the file:

The path method accepts three arguments:

URL path The method to be accessed A name for the route for reference purposes.

For example, the second path maps the token URL to the get_token method in the views.

On the server-side of the Django application, we need to modify the urls.py file to map to the stories URLs, so locate the file: storiesserver/storiesserver/urls.py and replace the contents of this file with:

Ngrok

To expose the Django application to the Internet and our Android devices during development, we will be using Ngrok. After connecting your account, we can start an HTTP tunnel which forwards to our Django web application port, 8000:

When the tunnel has been created, you will see the public URL which looks something like: https://xxxxxxxx.ngrok.io. Then you need to modify the storiesserver/storiesserver/settings.py file, by adding the "xxxxxxxx.ngrok.io", "10.0.2.2" and "localhost" strings to the ALLOWED_HOSTS variable. The 10.0.2.2 address is the way the Android emulator access localhost in your computer.

Your ALLOWED_HOSTS variable should look like this after the alteration:

Then to access the token URL, you would access this URL: https://xxxxxxxx.ngrok.io/stories/token.

At this point, you have built the server component which can generate tokens, archive video recording and deliver video recording URL. Next, you are going to build an Android application that acts as a client to this server application. With this mobile application, you can record videos and watch the video recordings.

Client Side

Fire up Android Studio, create a new project and select “Empty Activity” for your project template. For the minimum SDK, choose “API 16: Android 4.1 (Jelly Bean)” and for the language, choose “Kotlin”.

Dependencies

The first thing needed when building a project in Android Studio is to add any dependencies needed. Open the build.gradle in project level and add the following line inside the repositories block which is located inside the allprojects block. Then sync the file.

The second thing you have to do is to add dependencies on the file, which has the same name build.gradle but in application level (or module level). Add these lines inside the dependencies block. Do not forget to sync the file.

This project uses five additional libraries, these are:

Vonage Video SDK (OpenTok) OkHttp library to send requests to our backend server, Gson library to parse JSON response, EasyPermissions library to handle permissions when our Android application asks permissions to use camera and microphone, Coroutines library to handle non-blocking and blocking code conveniently.

Network Security Config

This step is optional. If you want to test the application with an emulator and do not want to use Ngrok, then you need to create a network configuration file. Create the xml directory inside the res directory, then create a new file called network_security_config.xml file inside the xml directory. Copy the following into it:

It means you can develop the application without the HTTPS protocol for the backend URL.

Android Manifest

To activate this network configuration, open the AndroidManifest.xml file and add the following attribute into application node:

Then add the following inside the manifest node.

We need these two additions because we want to connect our mobile application to our backend server.

While we’re in this file, let’s create references to an additional two activities which will be created later. Add these lines after the only activity node.

Layout

We have three Activities, but we need to create 3 layouts for these Activities. We also need to create an additional layout for row layout in a RecyclerView used within the MainActivity.

First, create the row layout by creating a new file named row.xml within the app/src/main/res/layout directory. Copy the following XML into this new file:

The above defines the creation of a button, which will be used to launch an Activity to watch the story or the video.

Next, we need to create a layout to display a Video. Create a new file named activity_viewing_story.xml in the layout directory, and add the following XML to the file:

The layout contains a WebView which will render the video.

Next, we have to create the activity_creating_story.xml file. This is the layout used by the Activity to create a video. Delete the content of the file and add the following code to it:

The FrameLayout with the publisher ID is used by the Video SDK to display the video which is being sent to the Video server. The purpose of the button in this Activity is to stop the recording of the video and end the Activity.

Lastly, we need to edit the activity_main.xml file. This file contains the layout used by the MainActivity, which will list all stories (videos) that have been created. The file will also contain a button to launch the Activity to create a video. Replace the contents of this file with the following XML to it:

Adding Server URL

Let’s define the server URL within the strings.xml file which can be found in the values directory. Do this by adding the following to your resources node:

If you are using Ngrok though, change it to the following example (make sure to replace xxxxx with your ngrok URL):

Classes and Activities

First, we’ll need to create the necessary classes for a RecyclerView. A RecyclerView needs an adapter and a holder. Create a holder file by creating the file with the name StoryViewHolder.kt within the package directory. The package will be something similar to com.example.storiesapplication which is located inside the java directory. Copy the following code into this new file:

For every class or Activity file you create, make sure you change the com.example.storiesapplication package to your package if your package is different.

This is a standard holder class where you set the text of the button with a string parameter and set a callback for the button.

After creating the holder class, we need an adapter class. An adapter is a bridge between data and the view of RecyclerView. Create a new file within the java/package/ directory called StoryAdapter.kt file and add the following code in this file:

The onCreateViewHolder method inflates the row layout and creates an instance of the holder class. The onBindViewHolder method sets the data to a specific row of the RecyclerView, and the getItemCount method returns the number of items stored.

It’s now time to create the RecyclerView in the MainActivity. Modify the MainActivity.kt file, by replacing the contents with the following:

The onCreate method adds a callback to the floating button in this Activity, which will call the getToken method to get the token, the session, and the API key before passing them to the CreatingStoryActivity Activity. The RecyclerView also loads the video list, and for each row, we add a callback to call the ViewingStoryActivity Activity.

In the onCreate method above, we request permissions for the camera, internet, and audio recording. If we have the permissions, we create a session object using the token, the session, and the API key. We also have to set the listener for this session object. We also set a callback to the button in this Activity. The button will send a request to stop archiving the video.

We have many methods required by the session listener. The most important one is the onConnected method, which will be called if our session has connected to the OpenTok server.

We create a publisher object and set the FrameLayout as the publisher’s view. We also have to connect our session object to this publisher object. Then we create a request object to start archiving the video.

At first, we get the video URL from the archive id by sending a request to our Django application. Then we load the URL in the WebView.

Launching the Application

Launch the application. Remember to use Ngrok or deploy the Django application on the cloud if you want to use an Android device. At first, you will see an empty screen and a floating button.

Press the floating button and the device will stream a video from your camera to the OpenTok server. When you have recorded enough for your story, press the “Upload Story” button on the screen.

You will be redirected back to the main screen, that now displays a list of your stories.

If you press the story row, you will be redirected to the viewing story screen. You can watch your video that you have recorded previously.

Conclusion

This application is far from perfect. If you notice, the recorded video is shorter than the recording session. That happens because it takes time to send a request to archive the video. On top of that, our stories list is a simple RecyclerView. You can convert them to a horizontal scroll. Each story is wrapped in a circle shape just like Instagram Stories looks like! We also do not have authentication and authorization. There is no owner for the story. This video is stored in the OpenTok server for some time. After that, the video will be deleted. You can choose to save the video somewhere else before that happens.

Resources

  • Check out our documentation for the Vonage Video Api here
  • The code for this blog post is on GitHub

Originally published at https://learn.vonage.com/blog/2021/03/23/build-social-media-style-stories-with-android-and-python/


Build Social Media Style Stories with Android and Python was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Vonage Dev


Print Share Comment Cite Upload Translate Updates
APA

Vonage Dev | Sciencx (2021-04-09T13:19:36+00:00) Build Social Media Style Stories with Android and Python. Retrieved from https://www.scien.cx/2021/04/09/build-social-media-style-stories-with-android-and-python/

MLA
" » Build Social Media Style Stories with Android and Python." Vonage Dev | Sciencx - Friday April 9, 2021, https://www.scien.cx/2021/04/09/build-social-media-style-stories-with-android-and-python/
HARVARD
Vonage Dev | Sciencx Friday April 9, 2021 » Build Social Media Style Stories with Android and Python., viewed ,<https://www.scien.cx/2021/04/09/build-social-media-style-stories-with-android-and-python/>
VANCOUVER
Vonage Dev | Sciencx - » Build Social Media Style Stories with Android and Python. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/04/09/build-social-media-style-stories-with-android-and-python/
CHICAGO
" » Build Social Media Style Stories with Android and Python." Vonage Dev | Sciencx - Accessed . https://www.scien.cx/2021/04/09/build-social-media-style-stories-with-android-and-python/
IEEE
" » Build Social Media Style Stories with Android and Python." Vonage Dev | Sciencx [Online]. Available: https://www.scien.cx/2021/04/09/build-social-media-style-stories-with-android-and-python/. [Accessed: ]
rf:citation
» Build Social Media Style Stories with Android and Python | Vonage Dev | Sciencx | https://www.scien.cx/2021/04/09/build-social-media-style-stories-with-android-and-python/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.