添加效果和过渡对象

[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayerIMFMediaEngine媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

[此 API 不受支持,将来可能会更改或不可用。]

在 DES 中,效果或过渡用两个 对象表示:

  • 时间线 对象表示时间线内的效果或过渡。 对于效果,时间线 对象支持 IAMTimelineEffect 接口。 对于转换,它支持 IAMTimelineTrans 接口。 这两种类型都支持 IAMTimelineObj 接口。
  • 子对象是实现效果或过渡数据处理的对象。 时间线 对象包含指向子对象的指针。

若要添加效果或切换效果,请执行以下步骤。

1. 创建 Timeline 对象

若要创建 时间线 对象,请调用 IAMTimeline::CreateEmptyNode 方法。 对于效果,将类型设置为等于 TIMELINE_MAJOR_TYPE_EFFECT ,或为切换设置 TIMELINE_MAJOR_TYPE_TRANSITION

以下示例创建一个转换对象:

IAMTimelineObj *pTransObj = NULL;
pTimeline->CreateEmptyNode(&pTransObj, TIMELINE_MAJOR_TYPE_TRANSITION);

2.指定子对象

时间线 对象充当另一个对象(称为子对象)的包装器,该对象执行实际工作。 子对象实现产生所需效果或转换的数据转换。 有关 DES 提供的过渡和效果的列表,请参阅 切换效果和效果

若要设置子对象,请对 时间线 对象调用 IAMTimelineObj::SetSubObjectGUID 方法,向其传递子对象的 CLSID) 类标识符 (。 DirectShow 为视频效果和视频过渡提供了一个枚举器,可用于获取 CLSID。 有关详细信息,请参阅 枚举效果和过渡

以下示例将 SMPTE 擦除转换 设置为子对象 :

hr = pTransObj->SetSubObjectGUID(CLSID_DxtJpeg);  // SMPTE Wipe

3.设置开始和停止时间

若要设置开始和停止时间,请调用 IAMTimelineObj::SetStartStop 方法。 这些时间相对于父对象的开始时间。 效果可以在同一对象内重叠,但转换不能。

以下示例将开始时间设置为 5 秒,将停止时间设置为 10 秒:

const REFERENCE_TIME ONE_SECOND = 10000000
hr = pTransObj->SetStartStop(5 * ONE_SECOND, 10 * ONE_SECOND);

呈现过渡时,基于 Progress 属性计算每个帧的转换进度,该属性规范化为 0.0 到 1.0 的范围。 DES 使用每个帧的开始时间来计算进度值。 这意味着,如果转换停止时间等于源停止时间, 则 Progress 值永远不会正好达到 1.0,因为最后一帧的开始时间略高于停止时间。 若要使过渡达到 1.0,请将切换停止时间设置为至少比源停止时间早一帧。

4. 将对象插入时间线

若要将对象插入时间线,请在父级上调用以下方法之一,具体取决于对象类型:

IAMTimelineEffectable::EffectInsBefore 方法中,必须指定效果的优先级。 当效果在同一对象上重叠时,它们将按优先级顺序应用。 音量信封音频效果是一个例外;有关详细信息,请参阅 音量信封效果 参考。 在合成中,所有音轨在应用该合成的音频效果之前是混合的。

由于转换不能在同一对象上重叠,因此它们没有优先级值。

以下示例将转换对象添加到轨道:

IAMTimelineTransable *pTransable = NULL;
hr = pTrack->QueryInterface(IID_IAMTimelineTransable, (void **)&pTransable);
hr = pTransable->TransAdd(pTransObj);  
pTransable->Release();

该示例在调用 AddTrans 之前查询 IAMTimelineTransable 接口的跟踪对象。

5. 设置属性

许多效果和过渡都支持自定义属性。 有关信息,请参阅 设置效果和过渡的属性

示例

下面的代码示例将 SMPTE 擦除转换添加到轨道。它假定跟踪对象已存在于时间线中。

IAMTimeline *pTL;
IAMTimelineTrack *pTrack;

// Create timeline with track (not shown).

// Create the transition object. 
IAMTimelineObj *pTransObj = NULL;
hr = pTL->CreateEmptyNode(&pTransObj, TIMELINE_MAJOR_TYPE_TRANSITION);

// Set the subobject. 
hr = pTransObj->SetSubObjectGUID(CLSID_DxtJpeg);  // SMPTE Wipe

// Set the start and stop times. 
hr = pTransObj->SetStartStop(50000000, 100000000);

// Insert the transition object into the timeline. 
IAMTimelineTransable *pTransable = NULL;
hr = pTrack->QueryInterface(IID_IAMTimelineTransable, (void **)&pTransable);
hr = pTransable->TransAdd(pTransObj);  
pTransable->Release();
pTransObj->Release();

使用效果和切换效果