2009-06-25 07:16:22 -07:00
|
|
|
|
/*
|
|
|
|
|
* 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 {
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sound player using mciSendSring command operation
|
|
|
|
|
/// </summary>
|
|
|
|
|
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;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// the number of Load failure
|
|
|
|
|
/// </summary>
|
|
|
|
|
int m_load_failed = 0;
|
|
|
|
|
|
|
|
|
|
~MediaPlayer() {
|
|
|
|
|
Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose() {
|
|
|
|
|
if ( m_loaded ) {
|
|
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
m_playing = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or Sets the speed
|
|
|
|
|
/// </summary>
|
|
|
|
|
public float Speed {
|
|
|
|
|
get {
|
|
|
|
|
return m_speed;
|
|
|
|
|
}
|
|
|
|
|
set {
|
|
|
|
|
m_speed = value;
|
|
|
|
|
SetSpeed( m_speed );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sets the speed
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="speed">the value of speed to set</param>
|
|
|
|
|
private void SetSpeed( float speed ) {
|
|
|
|
|
w_mciSendString( "set " + m_alias + " speed " + (int)(speed * 1000.0f) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or Sets the volume (0 >= volume >= 1000)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int Volume {
|
|
|
|
|
get {
|
|
|
|
|
if ( mute ) {
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return m_volume;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
set {
|
|
|
|
|
m_volume = value;
|
|
|
|
|
SetVolume( m_volume );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sets the volume (0 >= volume >= 1000)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="value"></param>
|
|
|
|
|
private void SetVolume( int value ) {
|
|
|
|
|
ReLoad();
|
|
|
|
|
w_mciSendString( "setaudio " + m_alias + " volume to " + value );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the volume (0 <= volume <= 1000)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or Sets whether sound is muted or not
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool IsMuted {
|
|
|
|
|
get {
|
|
|
|
|
return mute;
|
|
|
|
|
}
|
|
|
|
|
set {
|
|
|
|
|
bool old = mute;
|
|
|
|
|
mute = value;
|
|
|
|
|
if ( old != mute ) {
|
|
|
|
|
if ( mute ) {
|
|
|
|
|
SetVolume( 0 );
|
|
|
|
|
} else {
|
|
|
|
|
SetVolume( m_volume );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the pass of the sound file
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string SoundLocation {
|
|
|
|
|
get {
|
|
|
|
|
return m_filename;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// external declaration of mciSendString
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="s1">Command String</param>
|
|
|
|
|
/// <param name="s2">Return String</param>
|
|
|
|
|
/// <param name="i1">Return String Size</param>
|
|
|
|
|
/// <param name="i2">Callback Hwnd</param>
|
|
|
|
|
/// <returns>true when successed, false if not</returns>
|
|
|
|
|
[DllImport( "winmm.dll" )]
|
|
|
|
|
extern static int mciSendString( string s1, StringBuilder s2, int i1, int i2 );
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// mciSendString wrapper with exception handling
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="command">command sending to MCI</param>
|
|
|
|
|
/// <param name="result">returned string of mciSendString</param>
|
|
|
|
|
/// <returns>command successedd or not</returns>
|
|
|
|
|
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 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Closes sound file temporary
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public void UnLoad() {
|
|
|
|
|
if ( m_filename != "" ) {
|
|
|
|
|
Stop();
|
|
|
|
|
w_mciSendString( "close " + m_alias );
|
|
|
|
|
m_loaded = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Opens sound file which was closed with "UnLoad" method
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
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 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Opens sound file
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="filename">Path of sound file to open</param>
|
|
|
|
|
/// <returns>successed opening the file or not</returns>
|
|
|
|
|
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;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
m_alias = bocoree.Misc.getmd5( m_filename );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
#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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Plays sound from specified second
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="time">Sound position start to play</param>
|
|
|
|
|
/// <returns>true if play command successed</returns>
|
|
|
|
|
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() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Closes sound file
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>true if successed closing sound file</returns>
|
|
|
|
|
public bool Close() {
|
|
|
|
|
if ( m_filename == "" ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
Stop();
|
|
|
|
|
m_filename = "";
|
|
|
|
|
m_loaded = false;
|
|
|
|
|
return w_mciSendString( "close " + m_alias );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Plays sound from time 0 second
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>true if successed to play</returns>
|
|
|
|
|
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 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Seeks to specified position
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pos_second">position to seek in second</param>
|
|
|
|
|
/// <returns>true if successed to seek</returns>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Pauses sound
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>true if successed to pause</returns>
|
|
|
|
|
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 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the current playing position in millisecond
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>playing position in millisecond</returns>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the sound length in millisecond
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>Sound length in millisecond</returns>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Stops sound
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>true if successed to stop</returns>
|
|
|
|
|
public bool Stop() {
|
|
|
|
|
m_playing = false;
|
|
|
|
|
return w_mciSendString( "stop " + m_alias );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsPlaying {
|
|
|
|
|
get {
|
|
|
|
|
return m_playing;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|