Python takes you to generate a short video of super fire in your circle of friends

Time:2021-7-21

Python takes you to generate a short video of super fire in your circle of friends

1. Scene

If you often brush your voice and circle of WeChat friends, you will find that the recent short tiktok video is very hot!

Compared with the traditional pictures and videos, the former seems to be more personalized and compelling

Python takes you to generate a short video of super fire in your circle of friends

In addition to the traditional editing software can be achieved, is there any other faster and more convenient way? For example: one click generation, batch generation?

No more nonsense, this article will use Python to generate a short video of Jiugong grid, gracefully help you install a force in your circle of friends!

2. Preparation

Before the actual combat, use pip to install two dependencies, which are:

1. Video processing dependency   moviepy

2. Image processing dependency   PIL

#Install two dependencies
#Video processing
pip3 install moviepy

#Image processing dependency
pip3 install Pillow

3. Practice

Before the actual combat, first prepare a piece of original video material

Through   six   The first step is to convert the original video into a nine palace video

1. New processing folder

Create a new temporary folder and a new video output folder

def mkdir_folder(file_path):
    """
    Create a folder. If it doesn't exist, create it; Otherwise, it will not be dealt with
    :param file_path:
    :return:
    """
    if os.path.exists(file_path):
        return

    os.mkdir(file_path)

#New temporary folder and output folder
mkdir_folder(self.path_temp)
mkdir_folder(self.path_output)

2. Get the audio file and video basic information of the video

First, based on the original video, use moviepy   Build a   Videofileclip object, so as to obtain the video width, height, frame rate, duration and other information

self.video_raw_clip = VideoFileClip(file_path)

#Width and height
self.video_width, self.video_height = self.video_raw_clip.w, self.video_raw_clip.h

#Frame rate
self.fps = self.video_raw_clip.fps

#Video duration
self.during = self.video_raw_clip.duration

Then, the image is extracted from the video   BGM audio object and write to the file

def get_audio_from_video(video_raw_clip, output_path):
    """
    Extract audio from video
    :param video_ raw_ Clip: video clip object
    :param output_ Path: output audio file full path
    :return:
    """
    audio = video_raw_clip.audio
    audio.write_audiofile(output_path)

    return output_path

3. Processing video frames

We use the original video   The name of the clip object   iter_ Frame () method, loop to get all the video frames

It should be pointed out that in order to ensure the convenience of video synthesis, the file names of video frames are ordered in order

i = 1
​for frame in self.video_raw_clip.iter_frames():
     image = Image.fromarray(frame)

     #Temporary path (full path) for video frame picture saving
     frame_file_complete_path = self.path_temp + "%04d.jpg" % i

     i += 1

Each frame of the video is cut into nine pictures. We can explicitly specify the distance between the pictures, then calculate the width and height of the new canvas, and finally draw a picture with a white background

#1. Cut into 9 pictures and calculate the width and height of each picture
item_width = int(self.video_width / 3)
item_height = int(self.video_height / 3)

#2. New width and height
item_width_new = self.video_width + self.item_space * 2
item_height_new = self.video_height + self.item_space * 2

#3. Create a new canvas background
new_image = Image.new(image.mode, (item_width_new, item_height_new),
                              color='white')

Then, get the coordinate value of each area, add the interval offset to the horizontal and vertical second and third image area, and paste it to the new image above

#4. Cut the picture and paste it into the new canvas
#I: transverse, j: longitudinal
for i in range(0, 3):
   for j in range(0, 3):
        #Crop Region
        box = (j * item_width, i * item_height, (j + 1) * item_width, (i + 1) * item_height)

        #Crop the image according to the region
        crop_image = image.crop(box)

        #Horizontal and vertical blocks 2 and 3 should be offset
        x = 0 if j == 0 else (item_width + self.item_space) * j
        y = 0 if i == 0 else (item_height + self.item_space) * i

        #Paste 9 pictures into the background according to the coordinate values calculated above
        new_image.paste(crop_image, (int(x), int(y)))

        #Save image to local
        new_image.save(frame_file_complete_path)

4. Recombine video from a basket of pictures

The frame image generated in the previous step is converted into video according to the frame rate of the original video

It should be noted that in order to ensure that the generated video will not be disordered, it is best to sort the frame pictures by name once

def pics_to_video(pics_path, output_path, fps):
    """
    Picture to video
    pics_to_video('./../gif_temp/', './../video_temp/temp1.mp4', 20)
    :param pics_path:
    :param output_path:
    :return:
    """
    image_paths = list(map(lambda x: pics_path + x, os.listdir(pics_path)))

    #Note: there must be a sort to ensure that the order of all frames is consistent
    image_paths = sort_strings_with_emb_numbers(image_paths)

    #Filter out non images
    image_paths = list(filter(lambda image_path: image_path.endswith('.jpg'), image_paths))

    #Picture editing
    clip = ImageSequenceClip(image_paths,
                             fps=fps)

    clip.write_videofile(output_path)

5. Add BGM background music

Set the audio file of the original video to the video file generated in the previous step, and then write it to a new file

def video_with_audio(path_video_raw, path_bgm_raw, output):
    """
    Video to audio
    :return:
    """
    videoclip = VideoFileClip(path_video_raw)
    audioclip = AudioFileClip(path_bgm_raw)

    #Set the video and audio, and write it to the file
    videoclip.set_audio(audioclip).write_videofile(output,
                                                   codec='libx264',
                                                   audio_codec='aac',
                                                   temp_audiofile='temp-audio.m4a',
                                                   remove_temp=True
                                                   )

6. Delete temporary files

Use shutil to delete the temporary video files, including frame pictures and temporary video files

def remove_folder(file_path):
    """
    remove folders
    :param file_path:
    :return:
    """
    shutil.rmtree(file_path)

#Delete temporary files
remove_folder(self.path_temp)

4. Finally

Through the above series of operations, we can process a video into a nine palace video

I have all the source code in this article, including: generating two sets of code for nine palace video and pictures   Upload to the background and reply to “squared paper for practicing calligraphy 」 You can get all the source code

If you think the article is good, please  Like, share, leave a messageNext, because this will be the strongest driving force for me to continuously output more high-quality articles!

Recommended Today

STM32 network circuit design

In previous tweets《SMI interface of STM32 network》《MII and RMII interfaces of STM32 network》, all interfaces of STM32 Ethernet and external PHY are introduced. If some students are not familiar with SMI, MII and RMII interfaces, it is recommended to read the two articles mentioned above, otherwise they may not understand the following. ​ Zone 1:We […]