0

我正在使用第三方控件进行视频捕获,该控件将 .prx 文件用于某些输出属性,即输出大小。我试图将输出高度和宽度设置为尽可能大,同时保持用户实际屏幕尺寸的比例。

我相信 .prx 文件只是一个 XML 文件,但是当我将它作为 XMLDocument 打开然后保存时,我在尝试使用 Windows Media Encoder 打开时收到一条消息,指出“配置文件无效。(0xC00D0BC6)”。在运行代码之前,我能够毫无问题地打开同一个文件。

Dim prx As New XmlDocument()
prx.Load(Globals.appPath + prxFileName)
Dim prxWidth As XmlAttribute = prx.SelectSingleNode("/profile/streamconfig/wmmediatype/videoinfoheader/bitmadinfoheader/@biwidth")
Dim prxHeight As XmlAttribute = prx.SelectSingleNode("/profile/streamconfig/wmmediatype/videoinfoheader/bitmadinfoheader/@biheight")
prx.Save(Globals.appPath + prxFileName)

因此,无需对文件进行任何实际编辑,而是将其重新保存为 XMLDocument,配置文件就会变得无效。有没有办法在保持配置文件有效性的同时在代码中编辑 .prx 文件?

作为参考,下面是在文本编辑器中打开的有效 .prx 文件。

<profile version="589824" 
         storageformat="1" 
         name="myProfile" 
         description=""> 
               <streamconfig majortype="{73647561-0000-0010-8000-00AA00389B71}" 
               streamnumber="1" 
               streamname="Audio Stream" 
               inputname="Audio409" 
               bitrate="48000" 
               bufferwindow="3000" 
               reliabletransport="0" 
               decodercomplexity="" 
               rfc1766langid="en-us" 
> 
         <wmmediatype subtype="{00000161-0000-0010-8000-00AA00389B71}"  
               bfixedsizesamples="1" 
               btemporalcompression="0" 
               lsamplesize="1152"> 
       <waveformatex wFormatTag="353" 
                     nChannels="2" 
                     nSamplesPerSec="32000" 
                     nAvgBytesPerSec="6000" 
                     nBlockAlign="1152" 
                     wBitsPerSample="16" 
                     codecdata="008800001F0000000000"/> 
        </wmmediatype>
        </streamconfig>
               <streamconfig majortype="{73646976-0000-0010-8000-00AA00389B71}" 
               streamnumber="2" 
               streamname="Video Stream" 
               inputname="Video409" 
               bitrate="400000" 
               bufferwindow="3000" 
               reliabletransport="0" 
               decodercomplexity="AU" 
               rfc1766langid="en-us" 
> 
                 <videomediaprops maxkeyframespacing="80000000" 
                                 quality="100"/> 
         <wmmediatype subtype="{33564D57-0000-0010-8000-00AA00389B71}"  
               bfixedsizesamples="0" 
               btemporalcompression="1" 
               lsamplesize="0"> 
   <videoinfoheader dwbitrate="400000" 
                    dwbiterrorrate="0" 
                    avgtimeperframe="333333"> 
    <rcsource left="0" 
              top="0" 
              right="2000" 
              bottom="562"/> 
    <rctarget left="0" 
              top="0" 
              right="2000" 
              bottom="562"/> 
        <bitmapinfoheader biwidth="2000" 
                          biheight="562" 
                          biplanes="1" 
                          bibitcount="24" 
                          bicompression="WMV3" 
                          bisizeimage="0" 
                          bixpelspermeter="0" 
                          biypelspermeter="0" 
                          biclrused="0" 
                          biclrimportant="0"/> 
   </videoinfoheader>
        </wmmediatype>
        </streamconfig>
</profile> 

在这个问题的帮助下,尽管分辨率发生变化,视频捕获输出始终为 320x240,我稍微改变了策略以使用 IWMStreamConfig。

    Dim profileData As String
    Using reader As New StreamReader(File.OpenRead(Globals.appPath + prxFileName))
        profileData = reader.ReadToEnd()
    End Using

    Dim profileManager As IWMProfileManager
    Dim wmProfile As IWMProfile = Nothing
    Dim hr As Integer = WMLib.WMCreateProfileManager(profileManager)
    If hr >= 0 Then
        hr = profileManager.LoadProfileByData(profileData, wmProfile)
    End If

    If profileManager IsNot Nothing Then
        System.Runtime.InteropServices.Marshal.ReleaseComObject(profileManager)
        profileManager = Nothing
    End If

    Dim pConfig As IWMStreamConfig
    wmProfile.GetStream("Video Stream", pConfig)

现在我至少将流作为 IWMStreamConfig 对象,我觉得我越来越接近了。但是,如何编辑此 MSDN 文章中的 BITMAPINFOHEADER.biHeight 和 BITMAPINFOHEADER.biWidth?

http://msdn.microsoft.com/en-us/library/windows/desktop/dd756998(v=vs.85).aspx

SetBitRate 和 SetBufferWindow 出现在 InteliSense 中,但我不确定如何访问这些较低级别的属性。

4

2 回答 2

1

该文件是 Unicode。具体来说,基于 BOM 代码 0xFFFE 的 little-endian UTF-16。

由于看起来您使用的是 .NET,因此请尝试将 FileStream 包装在 StreamWriter 中:

Dim FS As FileStream = New FileStream(prxFile, FileMode.CreateNew)
Dim SW As StreamWriter = New StreamWriter(FS, new UnicodeEncoding(false, true))

然后您可以将整个字符串写入文件。

XmlDocument 的加载/保存方法采用扩展 TextWriter 的 StreamWriter。只需使用指定的编码以相同的方式创建它。

于 2013-02-27T00:08:17.710 回答
0

在十六进制编辑器中查看文件后,0x00每个字符之间都有有效的配置文件,文件以 开头0xFFFE,我假设有一些编码。一旦确定了这一点,我就使用流阅读器将文本读入字符串,并通过字符串操作进行更改。

棘手的部分是将所有内容写回文件。出于某种原因,无论我尝试将前两个十六进制字符写入文件的任何方式,它们都会被转换为四个不同的十六进制字符。解决方案是使用 FileStream 逐字节写入。

//Read in the initial profile
Dim profileData As String
Using reader As New StreamReader(File.OpenRead(prxFile))
    profileData = reader.ReadToEnd()
End Using

//Make changes to the profile with string manipulation

//Write the changed data back to the file including all the Hex characters
File.Delete(prxFile)
Dim FS As FileStream = New FileStream(prxFile, FileMode.CreateNew)
//Start by writing 0xFFFE
FS.WriteByte(&HFF)
FS.WriteByte(&HFE)
//Then write each character succeeded by 0x00
For Each Character As Char In profileData.ToCharArray
    FS.WriteByte(AscW(Character))
    FS.WriteByte(&H0)
Next
FS.Close()
于 2012-11-28T19:57:17.907 回答