1

我在使用时遇到了令人沮丧的砖墙:

projectItem.setInPoint(seconds)
projectItem.setOutPoint(seconds)

…大约 50% 的时间 I/O 点(在源窗口中)设置为 1 帧错误(有时 2 帧输出)。我觉得我已经尝试了一切来发现模式是什么,但它似乎完全是随机的。
 
我认为这可能与丢帧、可变帧速率、剪辑与序列不同或其他怪异有关,但错误发生在简单的恒定帧速率(如 25 fps)下。错误似乎没有押韵或原因(尽管在某些帧上始终出现相同的错误)。
 
子剪辑还有一个更大的问题,因为脚本环境认为所有子剪辑都从第 0 帧开始。
 
我已经尝试了所有方法,包括在滴答声、秒数或帧中工作,以及在它们之间进行转换。没有任何改变。
 
我想要完成的是在一组剪辑上设置输入/输出,运行脚本以从这些源剪辑中进行较小的剪辑,然后将剪辑恢复到原始 I/O 点。大部分工作都完成了,除了我无法通过这个错误将所有剪辑恢复到原始 I/O 点。
 
下面是我写的一个测试脚本。它获取当前的 I/O 位置,存储它们,然后将它们设置回相同的剪辑。一半的时间值不一样!啊!这使得无法准确设置剪辑 I/O。

function framesToSeconds (frames, fps)
{
    return frames / fps;
}

function secondsToFrames (sec, fps)
{
    return sec * fps;
}

/*---------------------------------------------------*/

var projItems = app.project.rootItem.children;
var clip = projItems[2];
var fps = clip.getFootageInterpretation().frameRate;

var setIn = clip.getInPoint().seconds;
var setOut = clip.getOutPoint().seconds;

var inFrame = secondsToFrames (setIn, fps);
var outFrame = secondsToFrames (setOut, fps);

var secIn = framesToSeconds (inFrame, fps);
var secOut = framesToSeconds (outFrame, fps);

clip.setInPoint( secIn );
clip.setOutPoint( secOut );

var setIn = clip.getInPoint().seconds;
var setOut = clip.getOutPoint().seconds;
4

2 回答 2

1

我又做了一些测试。尽管我不太了解错误的来源,但我相信我已经找到了解决方法。

我测试了 2 个 slug,每个 10 秒长,具有不同的帧速率,并通过循环运行它们并设置每个帧的 IO 点。我检查了每一帧以查看哪些帧返回错误。我发现的是:

test_25fps_1280x720.mov:帧 211,209,207,205,203,201 上的错误

test_29fps_1024x576.mov:帧 251,244,242,122,121,61 上的错误

这些错误不是随机的。每当我尝试在这些帧上设置入点或出点时,它总是会向下舍入 1 帧(在大约 50% 的帧关闭之前我错了,实际上不到 3%)。

我最好的猜测是存在一些精度错误,因为在某处进行了涉及大浮点数的计算。我无法确认,我也不太明白如何解决这个问题。但我确实发现我可以在设置入点和出点后测试它们,如果它不符合预期,我可以通过添加半帧的持续时间(以秒为单位)来重置点。一个完整的帧只会重复错误,但半帧会让 Premiere 向上舍入到正确的帧。

这是我的代码的主要部分:

/*---------------------------------------------------*/
function fixAnyFrameErrors (clip, inFrame, outFrame, fps, halfFrame)
/*---------------------------------------------------*/
{
    var inSecSet    = clip.getInPoint().seconds;
    var inFrameSet  = secondsToFrames (inSecSet, fps);
    var outSecSet   = clip.getOutPoint().seconds;
    var outFrameSet = secondsToFrames (outSecSet, fps);

    if ( parseFloat(inFrame) != parseFloat(inFrameSet) ) {
        clip.setInPoint( secIn + halfFrame );
    }

    if ( parseFloat(outFrame) != parseFloat(outFrameSet) ) {
        clip.setOutPoint( secOut + halfFrame );
    }
}

/*---------------------------------------------------*/

var tps = 254016000000; // 2.54016e11 ticks per second (Premiere Pro constant)

var projItems = app.project.rootItem.children;
var clip = projItems[2];
clip.addMetadata();
var fps = clip.getFootageInterpretation().frameRate;
var tpf = clip.videoInPoint.frame_rate;
var frameDuration = tpf / tps; // in seconds
var halfFrame = (frameDuration * 0.5);

var inFrame = 201;
var outFrame = 211;
  
var secIn  = framesToSeconds (inFrame,  fps);
var secOut = framesToSeconds (outFrame, fps);

clip.setInPoint ( secIn  );
clip.setOutPoint( secOut );

fixAnyFrameErrors (clip, inFrame, outFrame, fps, halfFrame);
于 2020-02-10T16:50:18.577 回答
0

我的观察是:

(我们在设置标记时遇到问题。)

我们的计算是正确的,但 Premiere 将标记秒数设置为 8.35999999999606 而不是 8.36(25fps),标记显示为 8 秒 9 帧,但显示值为 8 秒 8 帧。

来自 Adob​​e 论坛: https ://community.adobe.com/t5/premiere-pro/clip-marker-different-start-end-time-in-seconds/mp/9309128?page=1

他们建议使用 epsilon 来检查一个值是否非常接近计算值。在示例中,差异为 0,00000000000394 - 这是非常低的值,应更正为 0。

我不想知道如果我们使用带有丢帧的帧率(例如 23.976)会发生什么......

编辑:在我的情况下,您必须更正现有标记内的时间,所以这不起作用。我会尝试添加半帧...

于 2020-10-20T15:02:50.987 回答