复制流而不解压缩数据

将流从一个文件复制到另一个文件的最简单且最常用的方法是检索其压缩状态下的示例,然后将其写入新文件,而无需解压缩并 recompressing 它们。 从处于压缩状态的文件中获取的样本称为流示例,因为它们不会改变其在流中的表示形式。 建议始终使用流示例来复制流,因为解压缩和 recompressing 数字媒体数据会降低质量。 如果必须从解压缩的数据复制流,请参阅 使用解压缩的示例复制流

可以使用压缩样本将两个或多个流连接到单个流,但前提是比特率完全相同。 此过程实质上与下述步骤相同,不同之处在于您必须读取多个原始文件才能获取所需的所有内容。 但是, (如果包含所有压缩流的所有 pbFormat 结构成员) ,则仅可将多个 文件中的 _ _ 压缩样本写入单个流。 若要合并来自不同格式的多个流中的数据,必须解压缩内容并将其重新压缩到目标流中。 此外,将两个或多个流中的数据合并为单个流时,必须将所有流的缓冲区窗口值一起添加,以获取新流的缓冲区窗口。 这是因为无法确定在一个流的末尾和另一个流的开头占用了多少缓冲区。

可以使用 IWMReaderAdvanced:: SetReceiveStreamSamples通过异步读取器检索流示例。 流示例传递到 IWMReaderCallbackAdvanced:: OnStreamSample,而不是 IWMReaderCallback:: OnSample。 如果要读取文件并检索某些压缩的流和某些已解压缩的流,则必须实现两种回叫方法。

同步读取器提供了更灵活的检索示例。 使用 IWMSyncReader:: SetReadStreamSamples可以在播放期间自由地在已压缩和解压缩的示例之间切换。

若要将整个流从一个 ASF 文件复制到一个新的 ASF 文件中,请执行以下步骤。 这些步骤使用同步读取器,因为这种类型的操作使用起来要简单得多。

  1. 通过调用 WMCreateSyncReader 函数创建同步读取器对象。
  2. 使用对 IWMSyncReader:: Open的调用在读取器中打开文件。
  3. 通过调用 IWMSyncReader:: QueryInterface,获取指向同步读取器对象的 IWMProfile接口的指针。
  4. 调用 IWMProfile:: GetStreamByNumber,检索所需流的属性。 这将检索指向所需流的流配置对象的 IWMStreamConfig 接口的指针。
  5. 获取流的 WM _ 媒体 _ 类型 结构的副本。 对 IWMMediaProps:: GetMediaType执行两次调用以获取结构的大小,第二次调用以获取结构本身。
  6. 通过调用 WMCreateProfileManager 函数创建配置文件管理器对象。
  7. 调用 IWMProfileManager:: CreateEmptyProfile 以创建新的配置文件 (或打开要向其中添加流) 的现有配置文件。 对新的配置文件调用 IWMProfile:: AddStream ,以从现有文件添加流。 添加流时,请使用在步骤4中获得的 IWMStreamConfig 指针。
  8. 使用对 WMCreateWriter 函数的调用创建编写器对象。 通过调用 IWMWriter:: SetProfile将新创建的配置文件设置为编写器中的活动配置文件。 通过调用 IWMWriter:: SetOutputFilename创建用于输出的文件。
  9. 对于每个与要复制的流或流相关联的输入,请调用 IWMWriter:: SetInputProps,并为 IWMInputMediaProps接口传递 NULL 。 这会通知编写器对象它不需要验证所传递的数据。 在步骤 14) (调用 BeginWriting 之前,必须进行此调用,否则读取对象可能无法对内容进行解码。
  10. 通过调用 IWMSyncReader:: SetReadStreamSamples 并将 fCompressed 参数设置为 True,将同步读取器设置为提供所选流的压缩流示例。
  11. 获取要复制的每个流的编解码器信息,并在写入前将编解码器信息添加到标头。 若要获取编解码器信息,请调用 IWMHeaderInfo2:: GetCodecInfoCountIWMHeaderInfo2:: GetCodecInfo 来枚举与读取器中文件关联的编解码器。 选择与流配置匹配的编解码器信息。 然后通过调用 IWMHeaderInfo3:: AddCodecInfo,并传递从读取器获取的信息,在编写器中设置编解码器信息。
  12. 通过调用 IWMWriter:: QueryInterface 获取指向 IWMWriterAdvanced接口的指针。
  13. 通过调用 IWMWriter:: BeginWriting将编写器设置为写入模式。
  14. IWMSyncReader:: GetNextSample进行重复调用,同时指定所需的流号。 接收样本时,通过调用 IWMWriterAdvanced:: WriteStreamSample将其传递到编写器。 对于视频流,应检查标志 (在每次调用 GetNextSample 时编写器设置的) 。 如果 _ _ 设置了 CLEANPOINT,则还必须在对 WriteStreamSample 的调用上设置它。
  15. 读取完成后,调用 IWMWriter:: EndWriting。 应传输流。

备注

不能使用流示例将图像流从一个文件复制到另一个文件。 若要复制图像流数据,请检索未压缩的示例,然后按通常的方式对其进行处理。

将数据从一个文件复制到另一个文件

使用解压缩的示例复制流