I was using ffmpeg to convert Line sticker from apng file to webm file. And the result is weird, some of them was converted successed and some of them failed. not sure what happend with these failed convert.
Here is my c# code to convert Line sticker to webm, and I use CliWrap to run ffmpeg command line.
async Task Main()
{
var downloadUrl = @"http://dl.stickershop.LINE.naver.jp/products/0/0/1/23303/iphone/stickerpack@2x.zip";
var arg = @$"-i pipe:.png -vf scale=512:512:force_original_aspect_ratio=decrease:flags=lanczos -pix_fmt yuva420p -c:v libvpx-vp9 -cpu-used 5 -minrate 50k -b:v 350k -maxrate 450k -to 00:00:02.900 -an -y -f webm pipe:1";
var errorCount = 0;
try
{
using (var hc = new HttpClient())
{
var imgsZip = await hc.GetStreamAsync(downloadUrl);
using (ZipArchive zipFile = new ZipArchive(imgsZip))
{
var files = zipFile.Entries.Where(entry => Regex.IsMatch(entry.FullName, @"animation@2x\/\d+\@2x.png"));
foreach (var entry in files)
{
try
{
using (var fileStream = File.Create(Path.Combine("D:", "Projects", "ffmpeg", "Temp", $"{Path.GetFileNameWithoutExtension(entry.Name)}.webm")))
using (var pngFileStream = File.Create(Path.Combine("D:", "Projects", "ffmpeg", "Temp", $"{entry.Name}")))
using (var entryStream = entry.Open())
using (MemoryStream ms = new MemoryStream())
{
entry.Open().CopyTo(pngFileStream);
var result = await Cli.Wrap("ffmpeg")
.WithArguments(arg)
.WithStandardInputPipe(PipeSource.FromStream(entryStream))
.WithStandardOutputPipe(PipeTarget.ToStream(ms))
.WithStandardErrorPipe(PipeTarget.ToFile(Path.Combine("D:", "Projects", "ffmpeg", "Temp", $"{Path.GetFileNameWithoutExtension(entry.Name)}Info.txt")))
.WithValidation(CommandResultValidation.ZeroExitCode)
.ExecuteAsync();
ms.Seek(0, SeekOrigin.Begin);
ms.WriteTo(fileStream);
}
}
catch (Exception ex)
{
entry.FullName.Dump();
ex.Dump();
errorCount++;
}
}
}
}
}
catch (Exception ex)
{
ex.Dump();
}
$"Error Count:{errorCount.Dump()}".Dump();
}
This is the failed convert file's error information from ffmpeg:
And the successed convert file from ffmpeg infromation:
It's strange when I was manually converted these failed convert file from command line, and it will be converted successed.
The question is the resource of images are all the same apng file, so I just can't understan why some of files will convert failed from my c# code but also when I manually use command line will be converted successed?
I have written same exampe from C# to Python... and here is python code:
from io import BytesIO
import os
import re
import subprocess
import zipfile
import requests
downloadUrl = "http://dl.stickershop.LINE.naver.jp/products/0/0/1/23303/iphone/stickerpack@2x.zip"
args = [
'ffmpeg',
'-i', 'pipe:',
'-vf', 'scale=512:512:force_original_aspect_ratio=decrease:flags=lanczos',
'-pix_fmt', 'yuva420p',
'-c:v', 'libvpx-vp9',
'-cpu-used', '5',
'-minrate', '50k',
'-b:v', '350k',
'-maxrate', '450k', '-to', '00:00:02.900', '-an', '-y', '-f', 'webm', 'pipe:1'
]
imgsZip = requests.get(downloadUrl)
with zipfile.ZipFile(BytesIO(imgsZip.content)) as archive:
files = [file for file in archive.infolist() if re.match(
"animation@2x\/\d+\@2x.png", file.filename)]
for entry in files:
fileName = entry.filename.replace(
"animation@2x/", "").replace(".png", "")
rootPath = 'D:\\' + os.path.join("Projects", "ffmpeg", "Temp")
# original file
apngFile = os.path.join(rootPath, fileName+'.png')
# output file
webmFile = os.path.join(rootPath, fileName+'.webm')
# output info
infoFile = os.path.join(rootPath, fileName+'info.txt')
with archive.open(entry) as file, open(apngFile, 'wb') as output_apng, open(webmFile, 'wb') as output_webm, open(infoFile, 'wb') as output_info:
p = subprocess.Popen(args, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=output_info)
outputBytes = p.communicate(input=file.read())[0]
output_webm.write(outputBytes)
file.seek(0)
output_apng.write(file.read())
And you can try it,the result will be the as same as C#.