将 .osp OpenShot 项目导出到 ffmpeg 脚本作为视频导出冻结或因交换地狱崩溃的解决方法
Export .osp OpenShot project to ffmpeg script as workaround to video export freeze or crash by swap hell
我有一个很大的视频冲 35"。
我使用 OpenShot 剪切了 30 多个小序列并将它们连接成一个 25" 序列。
现在我尝试将结果导出为视频文件,但在 export/encoding 编码一个多小时后,OneShot 在 40% 到 80% 之间随机崩溃或冻结。它看起来是内存韭菜和内存分配拒绝的交换饱和,因为没有 space 剩余。
我试过 x264(mp4) 和 vp8(webm) 编码,但没有任何效果。
我打开了 .osp 文件,它是一个很大的 json 文件,所有的剪辑都是这样引用的:
{
clips:[
{
title: "<clipFileName.ext>",
start:<seconds>.<decimals>,
end:<seconds>.<decimals>,
position:<seconds>.<decimals>
}
]
}
title
如果不重命名就是inputFileName。
start
从输入文件开始的剪辑开始时间
end
从输入文件开始的剪辑结束时间
position
输出文件时间轴中的剪辑开始位置
我读过 ffmpeg can extract video parts / subclip / sequences with cut function :
ffmpeg -ss 00:00:09.000 -i input.mp4 -to 00:00:20 output.mp4
时间可以是 hh:mm:ss.xxx
或 hh:mm:ss
或任意数量的 seconds
,允许小数。
我也读过 ffmpeg can concat sequences :
ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" output.ts
那么,如何使用这些项目数据对我的视频进行编码?
所以我构建了以下脚本来将所有剪辑提取为视频文件,然后将它们连接起来:
function parser(e){
const commandList = [];
const outputFilesName = []
const reader = new FileReader();
reader.onload = function(){
const j = JSON.parse(reader.result);
j.clips.forEach(function(c){
const fileName = f3d(c.position) + '.ts';
outputFilesName.push(fileName);
let cmd = `ffmpeg -i ${c.title} -ss ${f3d(c.start)} -to ${f3d(c.end)} `;
cmd+= `-c copy -bsf:v h264_mp4toannexb -acodec libmp3lame -ab 128k -f mpegts `;
cmd+= fileName;
commandList.push(cmd);
});
const script = `Go to your video rush folder and run the following script :
${commandList.join(' && ')} && ffmpeg -i "concat:${outputFilesName.join('|')}" -c copy concatenated.mp4`
document.getElementById('commands').innerHTML = script;
};
reader.readAsText(e.target.files[0]);
}
document.getElementById('osp').addEventListener('change', parser, false);
function f3d(floatNumber){
return Math.round(floatNumber*1000)/1000;
}
<input id="osp" type="file" accept=".osp"/>
<pre id="commands"></pre>
我有一个很大的视频冲 35"。
我使用 OpenShot 剪切了 30 多个小序列并将它们连接成一个 25" 序列。
现在我尝试将结果导出为视频文件,但在 export/encoding 编码一个多小时后,OneShot 在 40% 到 80% 之间随机崩溃或冻结。它看起来是内存韭菜和内存分配拒绝的交换饱和,因为没有 space 剩余。
我试过 x264(mp4) 和 vp8(webm) 编码,但没有任何效果。
我打开了 .osp 文件,它是一个很大的 json 文件,所有的剪辑都是这样引用的:
{
clips:[
{
title: "<clipFileName.ext>",
start:<seconds>.<decimals>,
end:<seconds>.<decimals>,
position:<seconds>.<decimals>
}
]
}
title
如果不重命名就是inputFileName。start
从输入文件开始的剪辑开始时间end
从输入文件开始的剪辑结束时间position
输出文件时间轴中的剪辑开始位置
我读过 ffmpeg can extract video parts / subclip / sequences with cut function :
ffmpeg -ss 00:00:09.000 -i input.mp4 -to 00:00:20 output.mp4
时间可以是 hh:mm:ss.xxx
或 hh:mm:ss
或任意数量的 seconds
,允许小数。
我也读过 ffmpeg can concat sequences :
ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" output.ts
那么,如何使用这些项目数据对我的视频进行编码?
所以我构建了以下脚本来将所有剪辑提取为视频文件,然后将它们连接起来:
function parser(e){
const commandList = [];
const outputFilesName = []
const reader = new FileReader();
reader.onload = function(){
const j = JSON.parse(reader.result);
j.clips.forEach(function(c){
const fileName = f3d(c.position) + '.ts';
outputFilesName.push(fileName);
let cmd = `ffmpeg -i ${c.title} -ss ${f3d(c.start)} -to ${f3d(c.end)} `;
cmd+= `-c copy -bsf:v h264_mp4toannexb -acodec libmp3lame -ab 128k -f mpegts `;
cmd+= fileName;
commandList.push(cmd);
});
const script = `Go to your video rush folder and run the following script :
${commandList.join(' && ')} && ffmpeg -i "concat:${outputFilesName.join('|')}" -c copy concatenated.mp4`
document.getElementById('commands').innerHTML = script;
};
reader.readAsText(e.target.files[0]);
}
document.getElementById('osp').addEventListener('change', parser, false);
function f3d(floatNumber){
return Math.round(floatNumber*1000)/1000;
}
<input id="osp" type="file" accept=".osp"/>
<pre id="commands"></pre>