using System;
using System.Text;
using System.Runtime.InteropServices;
namespace BSE.Platten.Audio.WMFSDK
{
/// <summary>
/// Summary description for wmainfo.
/// </summary>
/// <remarks></remarks>
/// <copyright>Copyright � 2004 MCH Messe Basel AG</copyright>
public class CMetaDataEditor : IDisposable
{
#region Enumerationen
#endregion
#region Konstanten
#endregion
#region FieldsPublic
#endregion
#region FieldsProtected
#endregion
#region FieldsPrivate
private bool m_bisDisposed = false;
private IWMHeaderInfo3 m_IWMHeaderInfo3;
#endregion
#region Properties
#endregion
#region MethodsPublic
/// <summary>
/// Konstruktor der Klasse wmainfo.
/// </summary>
public CMetaDataEditor()
{
//
// TODO: Add constructor logic here
//
}
public AudioMetaData GetMediaMetaData(string pwszFileName)
{
AudioMetaData audioMetaData = new AudioMetaData();
try
{
ushort wStreamNum = 0xFFFF;
ushort wAttributeCount;
IWMMetadataEditor iWMMetadataEditor = WM.CreateEditor();
iWMMetadataEditor.Open( pwszFileName ) ;
m_IWMHeaderInfo3 = ( IWMHeaderInfo3 )iWMMetadataEditor;
m_IWMHeaderInfo3.GetAttributeCount(wStreamNum, out wAttributeCount );
for( ushort wAttribIndex = 0; wAttribIndex < wAttributeCount; wAttribIndex++)
{
WMT_ATTR_DATATYPE wAttribType;
string pwszAttribName = null;
byte[] pbAttribValue = null;
ushort wAttribNameLen = 0;
ushort wAttribValueLen = 0;
try
{
m_IWMHeaderInfo3.GetAttributeByIndex(wAttribIndex,
ref wStreamNum,
pwszAttribName,
ref wAttribNameLen,
out wAttribType,
pbAttribValue,
ref wAttribValueLen);
pbAttribValue = new byte[wAttribValueLen];
pwszAttribName = new String((char)0, wAttribNameLen);
m_IWMHeaderInfo3.GetAttributeByIndex(wAttribIndex,
ref wStreamNum,
pwszAttribName,
ref wAttribNameLen,
out wAttribType,
pbAttribValue,
ref wAttribValueLen);
SetMediaMetaDataObjects(
wAttribIndex,
wStreamNum,
pwszAttribName,
wAttribType,
0,
pbAttribValue,
wAttribValueLen,
ref audioMetaData);
}
catch { }
}
}
catch (Exception)
{
throw;
}
return audioMetaData;
}
public void SetAttribute(string pwszFileName,string pwszAttribName,
ushort wAttribType, string pwszAttribValue )
{
try
{
ushort wStreamNum = 0;
byte[] pbAttribValue;
int nAttribValueLen;
WMT_ATTR_DATATYPE AttribDataType = (WMT_ATTR_DATATYPE)wAttribType;
if ( !TranslateAttrib( AttribDataType, pwszAttribValue, out pbAttribValue, out nAttribValueLen ) )
{
return;
}
IWMMetadataEditor iWMMetadataEditor = WM.CreateEditor();
iWMMetadataEditor.Open( pwszFileName ) ;
m_IWMHeaderInfo3 = null;
m_IWMHeaderInfo3 = ( IWMHeaderInfo3 )iWMMetadataEditor;
m_IWMHeaderInfo3.SetAttribute( wStreamNum,
pwszAttribName,
AttribDataType,
pbAttribValue,
(ushort)nAttribValueLen );
iWMMetadataEditor.Flush();
iWMMetadataEditor.Close();
}
catch (Exception e )
{
throw e;
}
}
#region IDisposable Members
protected void Dispose(bool bdisposing)
{
if (!m_bisDisposed)
{
if (bdisposing)
{
// No managed resources to clear up...
}
// Clear up unmanaged resources
if (m_IWMHeaderInfo3 != null)
{
((IWMMetadataEditor) m_IWMHeaderInfo3).Close();
}
}
m_bisDisposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~CMetaDataEditor()
{
Dispose(false);
}
#endregion
#endregion
#region MethodsProtected
#endregion
#region MethodsPrivate
private void SetMediaMetaDataObjects(ushort wIndex,
ushort wStream,
string pwszName,
WMT_ATTR_DATATYPE AttribDataType,
ushort wLangID,
byte[] pbValue,
uint dwValueLen,
ref AudioMetaData mediaMetaData)
{
string pwszValue = String.Empty;
//
// Make the data type string
//
string pwszType = "Unknown";
string[] pTypes = { "DWORD", "STRING", "BINARY", "BOOL", "QWORD", "WORD", "GUID" };
if( pTypes.Length > Convert.ToInt32(AttribDataType) )
{
pwszType = pTypes[Convert.ToInt32(AttribDataType)];
}
//
// The attribute value.
//
switch ( AttribDataType )
{
// String
case WMT_ATTR_DATATYPE.WMT_TYPE_STRING:
if ( 0 == dwValueLen )
{
pwszValue = "***** NULL *****";
}
else
{
if ( ( 0xFE == Convert.ToInt16( pbValue[0] ) ) &&
( 0xFF == Convert.ToInt16( pbValue[1] ) ) )
{
pwszValue = "\"UTF-16LE BOM+\"";
if( 4 <= dwValueLen )
{
for ( int i = 0; i < pbValue.Length - 2; i += 2 )
{
pwszValue += Convert.ToString( BitConverter.ToChar( pbValue, i ) );
}
}
pwszValue = pwszValue + "\"" ;
}
else if ( ( 0xFF == Convert.ToInt16( pbValue[0] ) ) &&
( 0xFE == Convert.ToInt16( pbValue[1] ) ) )
{
pwszValue = "\"UTF-16BE BOM+\"";
if( 4 <= dwValueLen )
{
for ( int i = 0; i < pbValue.Length - 2; i += 2 )
{
pwszValue += Convert.ToString( BitConverter.ToChar( pbValue, i ) );
}
}
pwszValue = pwszValue + "\"" ;
}
else
{
if( 2 <= dwValueLen )
{
for ( int i = 0; i < pbValue.Length - 2; i += 2 )
{
pwszValue += Convert.ToString( BitConverter.ToChar( pbValue, i ) );
}
}
}
}
break;
// Binary
case WMT_ATTR_DATATYPE.WMT_TYPE_BINARY:
pwszValue = "[" + dwValueLen.ToString() + " bytes]";
break;
// Boolean
case WMT_ATTR_DATATYPE.WMT_TYPE_BOOL:
if ( BitConverter.ToBoolean( pbValue, 0 ) )
{
pwszValue = "True";
}
else
{
pwszValue = "False";
}
break;
// DWORD
case WMT_ATTR_DATATYPE.WMT_TYPE_DWORD:
uint dwValue = BitConverter.ToUInt32( pbValue, 0 );
pwszValue = dwValue.ToString( );
break;
// QWORD
case WMT_ATTR_DATATYPE.WMT_TYPE_QWORD:
ulong qwValue = BitConverter.ToUInt64( pbValue, 0 );
pwszValue = qwValue.ToString( );
break;
// WORD
case WMT_ATTR_DATATYPE.WMT_TYPE_WORD:
uint wValue = BitConverter.ToUInt16( pbValue, 0 );
pwszValue = wValue.ToString( );
break;
// GUID
case WMT_ATTR_DATATYPE.WMT_TYPE_GUID:
pwszValue = BitConverter.ToString( pbValue, 0, pbValue.Length );
break;
default:
break;
}
switch(pwszName.TrimEnd('\0'))
{
case WM.g_wszWMDuration:
mediaMetaData.Duration = Convert.ToInt64(pwszValue.ToString());
break;
case WM.g_wszWMBitrate:
mediaMetaData.Bitrate = Convert.ToInt32(pwszValue.ToString());
break;
case WM.g_wszWMTrackNumber:
mediaMetaData.WMTrackNumber = pwszValue;
break;
case WM.g_wszWMAuthor:
mediaMetaData.Author = pwszValue;
break;
case WM.g_wszWMAlbumArtist:
mediaMetaData.WMAlbumArtist = pwszValue;
break;
case WM.g_wszWMAlbumTitle:
mediaMetaData.WMAlbumTitle = pwszValue;
break;
case WM.g_wszWMGenre:
mediaMetaData.WMGenre = pwszValue;
break;
case WM.g_wszWMTitle:
mediaMetaData.Title = pwszValue;
break;
case WM.g_wszWMYear:
mediaMetaData.WMYear = pwszValue;
break;
}
}
//------------------------------------------------------------------------------
// Name: TranslateAttrib()
// Desc: Converts attributes to byte arrays.
//------------------------------------------------------------------------------
private bool TranslateAttrib( WMT_ATTR_DATATYPE AttribDataType, string pwszValue, out byte [] pbValue, out int nValueLength )
{
switch( AttribDataType )
{
case WMT_ATTR_DATATYPE.WMT_TYPE_DWORD:
nValueLength = 4;
uint[] pdwAttribValue = new uint[1] { Convert.ToUInt32( pwszValue ) };
pbValue = new Byte[nValueLength];
Buffer.BlockCopy( pdwAttribValue, 0, pbValue, 0, nValueLength );
return( true );
case WMT_ATTR_DATATYPE.WMT_TYPE_WORD:
nValueLength = 2;
ushort[] pwAttribValue = new ushort[1] { Convert.ToUInt16( pwszValue ) };
pbValue = new Byte[nValueLength];
Buffer.BlockCopy( pwAttribValue, 0, pbValue, 0, nValueLength );
return( true );
case WMT_ATTR_DATATYPE.WMT_TYPE_QWORD:
nValueLength = 8;
ulong[] pqwAttribValue = new ulong[1] { Convert.ToUInt64( pwszValue ) };
pbValue = new Byte[nValueLength];
Buffer.BlockCopy( pqwAttribValue, 0, pbValue, 0, nValueLength );
return( true );
case WMT_ATTR_DATATYPE.WMT_TYPE_STRING:
nValueLength = ( ushort )( ( pwszValue.Length + 1 ) * 2 );
pbValue = new Byte[ nValueLength ];
Buffer.BlockCopy( pwszValue.ToCharArray(), 0, pbValue, 0, pwszValue.Length * 2 );
pbValue[ nValueLength - 2 ] = 0;
pbValue[ nValueLength - 1 ] = 0;
return( true );
case WMT_ATTR_DATATYPE.WMT_TYPE_BOOL:
nValueLength = 4;
pdwAttribValue = new uint[1] { Convert.ToUInt32( pwszValue ) };
if ( pdwAttribValue[0] != 0 )
{
pdwAttribValue[0] = 1;
}
pbValue = new Byte[nValueLength];
Buffer.BlockCopy( pdwAttribValue, 0, pbValue, 0, nValueLength );
return( true );
default:
pbValue = null;
nValueLength = 0;
Console.WriteLine( "Unsupported data type." );
return( false );
}
}
#endregion
}
}