当前位置: 首页 > 工具软件 > AlphaPlayer > 使用案例 >

AlphaPlayer 脚本生成素材

幸乐湛
2023-12-01

文档:https://github.com/bytedance/AlphaPlayer

AlphaPlayer是直播中台使用的一个视频动画特效SDK,可以通过制作Alpha通道分离的视频素材,再在客户端上通过OpenGL ES重新实现Alpha通道和RGB通道的混合,从而实现在端上播放带透明通道的视频。

作为技术生成脚本的过程梳理下:

官方给出的命令:

python convertAlphaVideo.py --dir 'your pictures parent file path'

1.看这个命令首先电脑配置:Python环境

2.用到官方给的Python脚本:convertAlphaVideo.py 

官方给出的有些问题,修改了下才能跑通,已给官方提PR,脚本在下面分享给大家:convertAlphaVideo.py 

3.需要一系列的序列帧,就是一套帧图片,然后将这些帧图片生成一个MP4文件

4.这一步简单,但是经常被忽略,就是修改所有图片的名字,对所有图片重命名为5个字符的名字,比如:00001.png   00002.png

5.运行脚本生成目标礼物视频MP4

个人GitHub:  https://github.com/HuaDanJson  QQ : 381266395

修改后的:convertAlphaVideo.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import os
import subprocess
import sys
import shutil
import argparse

isDebug = False
needZip = False
outputVideoPath = ""
imageDir = ""
srcPath = ""
maskPath = ""
outputPath = ""
oVideoFilePath = ""
fps = 15
bitrate = 3904


def main():
	parser = argparse.ArgumentParser(description='manual to this script')
	parser.add_argument('--file', type=str, default = None)
	parser.add_argument('--dir', type=str, default = None)
	parser.add_argument('--zip', type=str2bool, nargs='?', const=True, default = False, help="Activate zip mode.")
	parser.add_argument('--fps', type=int, default = 15)
	parser.add_argument('--bitrate', type=int, default = 3904)
	args = parser.parse_args()

	print("convertAlphaVideo.py running")
	global needZip
	needZip = args.zip
	fps = args.fps
	bitrate = args.bitrate
	print "args.zip: ", args.zip
	if not args.file is None:
		parseVideoFile(args.file)
	elif not args.dir is None:
		parseImageDir(args.dir)
	else:
		print("params is None!")
		return
	print("finish")


def str2bool(v):
    if isinstance(v, bool):
       return v
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
        raise argparse.ArgumentTypeError('Boolean value expected.')


def help():
	print("help ~")


def parseVideoFile(path):
	print(">>>>>>> paraseVideoFile, file is %s" % path)

	parentDir = os.path.basename(path)
	parentDir = parentDir.split('.')[0] + "/"

	initDir(parentDir)
	videoToImage(path, imageDir)
	parseImageList(imageDir)
	imagesToVideo(outputPath, oVideoFilePath)

	shutil.rmtree(parentDir + "temp/")
	print(">>>>>> convert alpha video finish, video file path is : %s" % oVideoFilePath)


def parseImageDir(path):
	parentDir = os.path.abspath(path) + "/"
	print(">>>>>>> paraseImageDir, dirName is %s" % parentDir)

	initDir(parentDir)
	parseImageList(parentDir)
	imagesToVideo(outputPath, oVideoFilePath)

	shutil.rmtree(parentDir + "temp/")
	print(">>>>>> convert alpha video finish, video file path is : %s" % oVideoFilePath)


def initDir(parentDir):
	global imageDir
	imageDir = parentDir + "temp/imageDir/"
	mkdir(imageDir)
	global srcPath
	srcPath = parentDir + "temp/source/"
	mkdir(srcPath)
	global maskPath
	maskPath = parentDir + "temp/mask/"
	mkdir(maskPath)
	global outputPath
	outputPath = parentDir + "temp/output/"
	mkdir(outputPath)
	global outputVideoPath
	outputVideoPath = parentDir + "output/"
	mkdir(outputVideoPath)

	global oVideoFilePath
	oVideoFilePath = outputVideoPath + "video.mp4"


def parseImageList(inputPath):
	fileList = os.listdir(inputPath)
	totalLength = len(fileList)
	progress = 0
	for fileName in fileList:
		if os.path.splitext(fileName)[1] == ".png":
			inputImageFile = inputPath + fileName
			srcImageFile = srcPath + os.path.splitext(fileName)[0] + ".jpg"
			tempMaskImageFile = maskPath + os.path.splitext(fileName)[0] + "_temp.jpg"
			maskImageFile = maskPath + os.path.splitext(fileName)[0] + ".jpg"
			outputImageFile = outputPath + os.path.splitext(fileName)[0] + ".jpg"

			removeAlpha(inputImageFile, srcImageFile)
			if needZip:
				separateAlphaChannel(inputImageFile, tempMaskImageFile)
				zipAlphaChannelPro(tempMaskImageFile, maskImageFile)
			else:
				separateAlphaChannel(inputImageFile, maskImageFile)
			appendImageLand(srcImageFile, maskImageFile, outputImageFile)

			deleteTempFile(srcImageFile)
			deleteTempFile(maskImageFile)
			deleteTempFile(tempMaskImageFile)

			progress += 1
			updateProgress(progress, totalLength)


def videoToImage(videoPath, imageDir):
	command = "ffmpeg -i {} -r {} {}%05d.png".format(videoPath, fps, imageDir)
	if isDebug:
		print (command)
	ret = subprocess.Popen(command, shell = True)
	ret.communicate()


def removeAlpha(imageSrc, imageDst):
	command = "convert {} -background black -alpha remove {}".format(imageSrc, imageDst)
	if isDebug:
		print (command)
	ret = subprocess.Popen(command, shell = True)
	ret.communicate()


def separateAlphaChannel(imageFileOne, imageFileTwo):
	command = "convert {} -channel A -separate {}".format(imageFileOne, imageFileTwo)
	if isDebug:
		print (command)
	ret = subprocess.Popen(command, shell = True)
	ret.communicate()


def zipAlphaChannel(imageSrc, imageDst):
	srcImage = cv2.imread(imageSrc)
	shape = srcImage.shape
	dstImage = np.zeros((int(shape[0]), int(shape[1])/3, int(shape[2])), np.uint8)
	dstShape = dstImage.shape

	height 		= dstShape[0]
	width 		= dstShape[1]
	channels 	= dstShape[2]

	for row in range(height):
		for col in range(width):
			for channel in range(channels):
				dstImage[row][col][channel] = srcImage[row][col * 3 + channel][0]
	cv2.imwrite(imageDst, dstImage)


def zipAlphaChannelPro(imageSrc, imageDst):
	srcImage = cv2.imread(imageSrc)
	shape = srcImage.shape
	dstImage = np.zeros((int(shape[0]), int(shape[1])/3, int(shape[2])), np.uint8)
	dstShape = dstImage.shape

	height 		= dstShape[0]
	width 		= dstShape[1]
	channels 	= dstShape[2]

	for row in range(height):
		for col in range(width):
			for channel in range(channels):
				dstImage[row][col][channel] = srcImage[row][col + channel * width][0]
	cv2.imwrite(imageDst, dstImage)


def appendImageLand(imageFileOne, imageFileTwo, imageFileAppend):
	command = "convert +append {} {} {}".format(imageFileTwo, imageFileOne, imageFileAppend)
	if isDebug:
		print (command)
	ret = subprocess.Popen(command, shell = True)
	ret.communicate()


def deleteTempFile(filePath):
	if os.path.exists(filePath):
		os.remove(filePath)


def imagesToVideo(imagesPath, videoFile):
	command = "ffmpeg -r {} -i {}%05d.jpg -vcodec libx264 -pix_fmt yuv420p -b {}k {}".format(fps, imagesPath, bitrate, videoFile)
	if isDebug:
		print (command)
	ret = subprocess.Popen(command, shell = True)
	ret.communicate()


def updateProgress(progress, total):
	percent = round(1.0 * progress / total * 100,2)
	sys.stdout.write('\rprogress : %s [%d/%d]'%(str(percent)+'%', progress, total))
	sys.stdout.flush()


def mkdir(path):
	folder = os.path.exists(path)
	if not folder:
		os.makedirs(path)


if __name__ == '__main__':
	main()

 类似资料: