A Guide to Video Steganography Using Python (2024)

Encrypt data in your video using the least significant bit

A Guide to Video Steganography Using Python (1)

·

Follow

Published in

Better Programming

·

6 min read

·

May 18, 2020

--

A Guide to Video Steganography Using Python (3)

Steganography is the practice of concealing a file, message, image, or video within another file, message, image, or video. It has existed for a long time, and nowadays, digital steganography is used to hide data inside images. We can hide all kinds of data by using different digital steganographic methods.

In this article, we are going to use a method known as Least Significant Bit (LSB) transformation to hide a text inside a video.

A Guide to Video Steganography Using Python (4)

Above is a representation of the digit 149 as an 8-bit binary digit, with its rightmost bit highlighted. If we change it to 0, we will get 10010100 (decimal equivalent of 148). If we change any other bit in the binary number above, the change would be much greater. So in this example, the rightmost bit is the least significant — changing it results in the least change to the original number.

A digital image is a representation of pixel values, and every pixel value will have numbers containing information regarding the pixel. A digital color image will have red, green, and blue channels and eight bits to represent each channel, so every channel can take a value from 0-255, and this value represents the intensity of the pixel. (R, G, B)=(0,0,0) is the representation of the color black and (255,255,255) represents the color white.

Take an array of pixels as an example and suppose we want to hide the character A in it. Let’s see how it’s done:

(R, G, B)= (11101010 11101001 11001010),(10111001,11001011,11101000),(11001001 00100100 11101001)

This is a pixel array, and we want to hide A in it. The ASCII value of A is 65. If we convert it to binary, we get 01000001. So if we use LSB transformation, we can change the LSB of all the numbers in our array and get:

(R,G, B)= (11101010 11101001 11001010),(10111000,11001010,11101000),(11001000 00100101 11101001)

Now that we have hidden A in the pixel array, let’s use Python to hide a text inside an image.

A Guide to Video Steganography Using Python (5)

This is the image that we are going to use. First, we will install the dependencies and then look at the code step by step.

1. Install the dependencies

We are going to use stegano library in Python. We can install it by running:

$pip install stegano

Now we need to import the library and the lsb class from it:

from stegano import lsb

Now that we have imported the lsb class, let’s use its hide() method to hide our text inside the image:

secret=lsb.hide('./lenna.png','hello world')

This will transform the LSB of our image and hide our message in it. Now we have to save the image:

secret.save('./encoded_image.png')

That’s it. With just three lines of code, we have hidden the message.

Image comparison

A Guide to Video Steganography Using Python (6)

As you can see, there is no visible difference between these two images.

To reveal the secret message, simply use the lsb.reveal() method with the image as the argument and the message will be printed:


lsb.reveal('./encoded_image.png')
Output:- hello world

We have used LSB transformation to hide data inside an image, but how can we use this to hide data inside a video?

A video is a collection of frames, and each frame is an image. So if we pull out all the frames from a video, we can use this method to store our data using LSB steganography and stitch those frames back into a video with the secret message.

A Guide to Video Steganography Using Python (7)

The original source video is quite long, so I have just used an eight-second portion of it.

1. Extracting frames from a video

To extract frames from a video, we can use the most popular computer vision library, OpenCv.

First, install OpenCv and import it:

import cv2

We have to read the video. Go through the video frame by frame and save all the images into a new directory.

To load the video, we run:

vidcap = cv2.VideoCapture("video.mp4")

This loads the video into vidcap. Now we can use the read method to read the frames from “video.mp4:"

success, image = vidcap.read()

We can define a loop to go through all the frames and save it with a unique filename that we can easily sort:

Once this is done, we are left with all the frames from the video.

But a video is not just a collection of images. There is audio as well. To extract that audio, we will use FFmpeg.

2. Extracting audio from a video

FFmpeg is a free and open-source command-line tool for transcoding multimedia files. It contains a set of shared audio and video libraries such as libavcodec, libavformat, and libavutil. With FFmpeg, you can extract audio files from a video, convert your PNG image files into video, and much more.

To install FFmpeg in Ubuntu, first update the package list:

$sudo apt update

Then run the command below to install FFmpeg:

$sudo apt install ffmpeg

To validate that FFmpeg is installed properly, run:

ffmpeg -version

If you get something like the message below, everything is OK:

ffmpeg version n4.1.4 Copyright (c) 2000-2019 the FFmpeg developers

To use FFmpeg in Python, we have to import call and STDOUT from the subprocess library:

from subprocess import call,STDOUT

And then we can run the code below in Python:

call(["ffmpeg", "-i","video.mp4" , "-q:a", "0", "-map", "a", "tmp/audio.mp3", "-y"],stdout=open(os.devnull, "w"), stderr=STDOUT)

This code will extract the audio from the given video file and save it as “audio.mp3” in the tmp folder. After we encode the frames with our text, we can then use this audio file to give our encoded video file the proper audio.

3. Encoding the text inside frames

Now that we have all the frames, we can divide the strings into small chunks and hide each chunk of the message inside a frame using the lsb.hide() method:

split_string is a helper function to split strings into small portions. As we do not need to hide all the text in the first frame itself, we divide the frames and hide it in many frames. The full code can be found on GitHub.

We have loaded a video, pulled it to as many frames as possible, and encoded it. Now we have to put together the frames together into a video.

4. Making video from frames

We can use FFmpeg to stitch together all our frames with a hidden message to form a video and then lay out the audio:

call(["ffmpeg", "-i", "tmp/frame%d.png" , "-vcodec", "png", "video.mov", "-y"],stdout=open(os.devnull, "w"), stderr=STDOUT)

Running the code above creates the video with our secret message hidden in it.

We can run the code below if we want sounds in our video:

call(["ffmpeg", "-i", "temp/video.mov", "-i", "temp/audio.mp3", "-codec", "copy","data/enc-" + str(file_name)+".mov", "-y"],stdout=open(os.devnull, "w"), stderr=STDOUT)

And we have done it. The output video is almost 900 MB. I have uploaded a small portion of the video to show that video quality is not affected by this method.

Now that we have done the hard part of encoding, let’s look at how a person can decode our video and read the message.

Decrypting the message from the video

We have to do the same steps as with encryption, but in the opposite order. So we extract all the frames from the video and extract the information from the LSB:

As you can see, with modern libraries and languages like Python, it is really simple to do steganography and cryptography.

The only problem with this method is that the new video is huge in size when compared to the original video. If we could reduce the size, it would be a good addition to this project.

The full code for this project can be found on GitHub.

A Guide to Video Steganography Using Python (2024)
Top Articles
Latest Posts
Article information

Author: Amb. Frankie Simonis

Last Updated:

Views: 5755

Rating: 4.6 / 5 (56 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Amb. Frankie Simonis

Birthday: 1998-02-19

Address: 64841 Delmar Isle, North Wiley, OR 74073

Phone: +17844167847676

Job: Forward IT Agent

Hobby: LARPing, Kitesurfing, Sewing, Digital arts, Sand art, Gardening, Dance

Introduction: My name is Amb. Frankie Simonis, I am a hilarious, enchanting, energetic, cooperative, innocent, cute, joyous person who loves writing and wants to share my knowledge and understanding with you.