/*
* MediaPlayer.cs
* Copyright (c) 2007-2009 kbinani
*
* This file is part of Boare.Lib.Media.
*
* Boare.Lib.Media is free software; you can redistribute it and/or
* modify it under the terms of the BSD License.
*
* Boare.Lib.Media is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Boare.Lib.Media {
///
/// Sound player using mciSendSring command operation
///
public class MediaPlayer : IDisposable {
private string m_filename = "";
const int FALSE = 0;
const int TRUE = 1;
bool pausing = false;
int m_volume = 1000;
bool mute = false;
string m_alias = "";
bool m_loaded = false;
float m_speed = 1.0f;
bool m_playing = false;
///
/// the number of Load failure
///
int m_load_failed = 0;
~MediaPlayer() {
Dispose();
}
public void Dispose() {
if ( m_loaded ) {
Close();
}
m_playing = false;
}
///
/// Gets or Sets the speed
///
public float Speed {
get {
return m_speed;
}
set {
m_speed = value;
SetSpeed( m_speed );
}
}
///
/// Sets the speed
///
/// the value of speed to set
private void SetSpeed( float speed ) {
w_mciSendString( "set " + m_alias + " speed " + (int)(speed * 1000.0f) );
}
///
/// Gets or Sets the volume (0 >= volume >= 1000)
///
public int Volume {
get {
if ( mute ) {
return 0;
} else {
return m_volume;
}
}
set {
m_volume = value;
SetVolume( m_volume );
}
}
///
/// Sets the volume (0 >= volume >= 1000)
///
///
private void SetVolume( int value ) {
ReLoad();
w_mciSendString( "setaudio " + m_alias + " volume to " + value );
}
///
/// Gets the volume (0 <= volume <= 1000)
///
///
private int GetVolume() {
ReLoad();
string str;
bool ret = w_mciSendString( "status " + m_alias + " volume", out str );
int v = m_volume;
if ( ret ) {
int v1;
if ( int.TryParse( str, out v1 ) ) {
v = v1;
}
}
#if DEBUG
Console.WriteLine( "MediaPlayer+GetVolume()" );
Console.WriteLine( " str=" + str );
Console.WriteLine( " volume=" + v );
#endif
return v;
}
///
/// Gets or Sets whether sound is muted or not
///
public bool IsMuted {
get {
return mute;
}
set {
bool old = mute;
mute = value;
if ( old != mute ) {
if ( mute ) {
SetVolume( 0 );
} else {
SetVolume( m_volume );
}
}
}
}
///
/// Gets the pass of the sound file
///
public string SoundLocation {
get {
return m_filename;
}
}
///
/// external declaration of mciSendString
///
/// Command String
/// Return String
/// Return String Size
/// Callback Hwnd
/// true when successed, false if not
[DllImport( "winmm.dll" )]
extern static int mciSendString( string s1, StringBuilder s2, int i1, int i2 );
///
/// mciSendString wrapper with exception handling
///
/// command sending to MCI
/// returned string of mciSendString
/// command successedd or not
static bool w_mciSendString( string command, out string result ) {
StringBuilder sb = new StringBuilder( 32 );
int io_status = 0;
result = "";
try {
io_status = mciSendString( command, sb, sb.Capacity, 0 );
result = sb.ToString();
} catch {
return false;
}
if ( io_status == 0 ) {
return true;
} else {
return false;
}
}
static bool w_mciSendString( string command ) {
string ret;
return w_mciSendString( command, out ret );
}
///
/// Closes sound file temporary
///
///
public void UnLoad() {
if ( m_filename != "" ) {
Stop();
w_mciSendString( "close " + m_alias );
m_loaded = false;
}
}
///
/// Opens sound file which was closed with "UnLoad" method
///
///
public void ReLoad() {
if ( m_filename != "" && !m_loaded && m_load_failed < 10 ) {
if ( Load( m_filename ) ) {
m_loaded = true;
if ( mute ) {
SetVolume( 0 );
} else {
SetVolume( m_volume );
}
}
}
}
///
/// Opens sound file
///
/// Path of sound file to open
/// successed opening the file or not
public bool Load( string filename ) {
#if DEBUG
Console.WriteLine( "MediaPlayer+Load(String)" );
Console.WriteLine( " filename=" + filename );
#endif
if ( m_filename != "" ) {
Close();
}
this.m_filename = filename;
m_alias = bocoree.misc.getmd5( m_filename );
#if DEBUG
Console.WriteLine( " m_alias=" + m_alias );
#endif
bool ret = w_mciSendString( "open \"" + filename + "\" type MPEGVIDEO2 alias " + m_alias );
if ( !ret ) {
ret = w_mciSendString( "open \"" + filename + "\" type MPEGVIDEO alias " + m_alias );
if ( !ret ) {
ret = w_mciSendString( "open \"" + filename + "\" alias " + m_alias );
}
}
#if DEBUG
Console.WriteLine( " w_mciSendString result=" + ret );
#endif
if ( ret ) {
m_loaded = true;
} else {
m_load_failed++;
}
#if DEBUG
m_volume = GetVolume();
Console.WriteLine( " m_volume=" + m_volume );
#endif
SetVolume( m_volume );
return ret;
}
///
/// Plays sound from specified second
///
/// Sound position start to play
/// true if play command successed
public bool PlayFrom( double time ) {
if ( m_filename == "" ) {
return false;
}
long position = (long)(time * 1000);
if ( !m_loaded ) {
ReLoad();
}
/*if ( mute ) {
EnterMute();
} else {
ExitMute();
}*/
SetSpeed( m_speed );
m_playing = true;
return w_mciSendString( "play " + m_alias + " from " + position.ToString() );
}
///
/// Closes sound file
///
/// true if successed closing sound file
public bool Close() {
if ( m_filename == "" ) {
return false;
}
Stop();
m_filename = "";
m_loaded = false;
return w_mciSendString( "close " + m_alias );
}
///
/// Plays sound from time 0 second
///
/// true if successed to play
public bool Play() {
if ( m_filename == "" ) {
return false;
}
if ( !m_loaded ) {
ReLoad();
}
/*if ( mute ) {
EnterMute();
} else {
ExitMute();
}*/
SetSpeed( m_speed );
m_playing = true;
if ( pausing ) {
//return w_mciSendString( "resume \"" + m_filename + "\"", null, 0, 0 );
return w_mciSendString( "resume " + m_alias );
} else {
//return w_mciSendString( "play \"" + m_filename + "\"", null, 0, 0 );
return w_mciSendString( "play " + m_alias );
}
}
///
/// Seeks to specified position
///
/// position to seek in second
/// true if successed to seek
public bool Seek( double pos_second ) {
if ( m_filename == "" ) {
return false;
}
if ( !m_loaded ) {
ReLoad();
}
long position = (long)(pos_second * 1000.0);
bool ret = w_mciSendString( "seek " + m_alias + " to " + position );
return ret;
}
///
/// Pauses sound
///
/// true if successed to pause
public bool Pause() {
if ( m_filename == "" ) {
return false;
}
if ( !m_loaded ) {
ReLoad();
}
m_playing = false;
pausing = true;
//return w_mciSendString( "pause \"" + m_filename + "\"", null, 0, 0 );
return w_mciSendString( "pause " + m_alias );
}
///
/// Gets the current playing position in millisecond
///
/// playing position in millisecond
public int GetPosition() {
if ( this.SoundLocation == "" ) {
return -1;
}
if ( !m_loaded ) {
ReLoad();
}
string ret;
w_mciSendString( "status " + m_alias + " position", out ret );
int pos;
try {
pos = int.Parse( ret );
} catch {
pos = -1;
}
return pos;
}
///
/// Gets the sound length in millisecond
///
/// Sound length in millisecond
public int GetLength() {
if ( this.SoundLocation == "" ) {
return -1;
}
if ( !m_loaded ) {
ReLoad();
}
string ret;
w_mciSendString( "status " + m_alias + " length", out ret );
int length = -1;
if ( int.TryParse( ret, out length ) ) {
return length;
} else {
return -1;
}
}
///
/// Stops sound
///
/// true if successed to stop
public bool Stop() {
m_playing = false;
return w_mciSendString( "stop " + m_alias );
}
public bool IsPlaying {
get {
return m_playing;
}
}
}
}