MCIsendstringでパスに日本語含まれていると再生されない

タグの編集
投稿者 winvis  (学生) 投稿日時 2009/11/14 09:56:24
DOBON.netさん(間違っていたらすいません><)のサイトのコードを、元に
mp3プレーヤーを作ってみたのですが・・・
日本語がパスに含まれていると再生してくれませんorz

    <System.Runtime.InteropServices.DllImport("winmm.dll", _
    CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _
Private Shared Function mciSendString(ByVal command As String, _
    ByVal buffer As System.Text.StringBuilder, _
    ByVal bufferSize As Integer, ByVal hwndCallback As IntPtr) As Integer
    End Function

    Private aliasName As String = "MediaFile"
    Dim cmd As String
    'Button1のClickイベントハンドラ
    Private Sub Button1_Click(ByVal sender As Object, _
            ByVal e As EventArgs) Handles Button1.Click
        '再生するファイル名
        Dim fileName As String = "C:\[eufonius][リフレクティア][リフレクティア (instrumental)].mp3"


        'ファイルを開く
        cmd = "open """ + fileName + """ type mpegvideo alias " + aliasName
        If mciSendString(cmd, Nothing, 0, IntPtr.Zero) <> 0 Then
            Return
        End If '再生する
        Me.Text = fileName
    End Sub

    'Button2のClickイベントハンドラ
    Private Sub Button2_Click(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles Button2.Click
        Dim cmd As String
        '再生しているWAVEを停止する
        cmd = "stop " + aliasName
        mciSendString(cmd, Nothing, 0, IntPtr.Zero)
        '閉じる
        cmd = "close " + aliasName
        mciSendString(cmd, Nothing, 0, IntPtr.Zero)
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        cmd = "play " + aliasName
        mciSendString(cmd, Nothing, 0, IntPtr.Zero)
    End Sub
投稿者 (削除されました)  () 投稿日時 2009/11/14 10:26:42
(削除されました)
投稿者 葉月  (社会人) 投稿日時 2009/11/14 10:30:19
原因は、コマンドを読むのに失敗しています。
サンプルを参考に直してください。
提示されたコードのmpegvideoは動画を再生するときに使います。
MP3などの音楽を再生するときは、MySoundを使います。
詳しくは、VB中学校のサンプルに、わかりやすく実用性の高いコードがあるので参考にしてください。
それから、MCIコマンド+コーデックでDivxなどの再生ができるようになります。
参考サイトで学習するのをお勧めします。

■サンプル
    ''' <summary> 
    ''' プレイヤーをOPENする。 
    ''' </summary> 
    ''' <param name="strFullPath">ファイルを再生するフルパス</param> 
    Public Sub Open(ByVal strFullPath As String)
     Me.SendString(String.Format("open ""{0}"" alias MySound notify", strFullPath))
    End Sub


■参考サイト
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/mci/
投稿者 winvis  (学生) 投稿日時 2009/11/15 10:32:41
ご回答ありがとうございます。
参考にしましたサンプルですが・・・SendStringは、Form1のメンバではありませんと出るのですが・・・
すいませんorz
投稿者 葉月  (社会人) 投稿日時 2009/11/15 16:26:35
参考にしてほしかっただけなので、先のコードを書いただけでは動きません。
私も動かないことを明記しなかったのでお気になさらないでください。

動くサンプルを提示します。
私の作ったツールから必要な情報だけを摘出したつもりでしたが、
確認がいい加減なので余計なメソッドとか混ざっています。

サンプルのため本来は、こうした方がいいという事柄はコメントに説明があります。

■サンプル
>>>Form1.cs
以下のコントロールをForm1に貼り付けてください。
テキストボックス×1
ボタン×1

Public Class Form1

    ' エイリアス名 
    ' 今回はサンプルなので定数にしていますが、 
    ' 別途判断するようにすればさまざまなファイルを動的に再生可能です。 
    Private Const STR_ALIAS As String = "MySound"

    ' 再生されているかの確認。 
    ' 今回はサンプルなのでフィールドを使います。 
    ' 私の場合はフィールドを使わず、ボタン(再生・一時停止兼用)のテキストの内容から判断しています。 
    Private flgPlay As Boolean = False

    ' MCIコマンドを再生するクラスのインスタンス名 
    Private objMciCmd As MciCommand

    Public Sub New()

        ' この呼び出しは、Windows フォーム デザイナで必要です。 
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。 
        objMciCmd = New MciCommand()
    End Sub

    ' ユーザーが再生中にプログラムを閉じる操作をした場合に必要。 
    Private Sub Form1_FormClosing(ByVal sender As System.ObjectByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        If Me.flgPlay Then
            objMciCmd.PlayerStop(STR_ALIAS)
        End If
    End Sub

    ' 再生 
    Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click
        ' ファイル名 
        Dim strDir As String = Me.TextBox1.Text

        If Not flgPlay And System.IO.File.Exists(strDir) Then
            Me.flgPlay = True
            objMciCmd.Open(strDir)
            objMciCmd.Play(STR_ALIAS)
        End If
    End Sub

    ' 終了 
    Private Sub Button2_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button2.Click

        If flgPlay Then
            Me.flgPlay = False
            objMciCmd.PlayerStop(STR_ALIAS)
        End If
    End Sub
 
End Class

投稿者 葉月  (社会人) 投稿日時 2009/11/15 16:29:29
新しいクラスを作成し、名前をMciCommandにしてください。

>>>MciCommand.vb

Public Class MciCommand

#Region "フィールド"

    ' 再生や停止といった一連の動作を行うmciコマンド 
    Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As StringByVal lpstrReturnString As StringByVal uReturnLength As IntegerByVal hwndCallback As IntegerAs Integer
    ' エラー内容を返すmciコマンド 
    Private Declare Function mciGetErrorString Lib "winmm.dll" Alias "mciGetErrorStringA" (ByVal fdwError As IntegerByVal lpszErrorText As StringByVal cchErrorText As IntegerAs Integer

    ' 再生時間 
    Private iPlayTime As Integer = 0

#End Region


#Region "プロパティ"

    ''' <summary> 
    ''' 再生時間を取得する。 
    ''' </summary> 
    Public Property GetPlayTime() As Integer
        Get
            Return Me.iPlayTime
        End Get
        Private Set(ByVal value As Integer)
            Me.iPlayTime = value
        End Set
    End Property

#End Region

#Region "メソッド(各種MCIコマンド)"
    ''' <summary> 
    ''' 対応したエラーメッセージを返す 
    ''' </summary> 
    ''' <param name="iAPIResult">対応したエラー</param> 
    ''' <returns>エラー内容</returns> 
    Private Function ErrorStringResult(ByVal iApiResult As IntegerAs String
        Dim strBuf As String = New String(" "c, 255)
        Dim strErrMsg As String

        Call mciGetErrorString(iApiResult, strBuf, strBuf.Length)

        strErrMsg = strBuf.Replace(Chr(0), "")
        Return strErrMsg.Replace(" """)
    End Function


    ''' <summary> 
    ''' mciSendStringのコマンドを送る 
    ''' </summary> 
    ''' <param name="strCmd">送るコマンド</param> 
    ''' <returns>コマンド</returns> 
    Private Function SendString(ByVal strCmd As StringAs Long

        If strCmd.EndsWith("length "Then
            '' バッファー 
            'Dim strBuf As String = New String(" "c, 255) 
            'mciSendString(strCmd, strBuf, strBuf.Length, 0) 
            Me.iPlayTime = Me.MciSendLengthResult(strCmd)
        Else
            SendString = mciSendString(strCmd, "", 0, 0)
        End If

        ' エラーの戻り値 
        Dim lResult As Long = SendString

        If lResult <> 0 Then
            ' エラーメッセージを受け取る。 
            Dim strErrMsg As String = ErrorStringResult(Integer.Parse(lResult.ToString()))
            Console.WriteLine("frmMain.cs SendString ErrorMessage:\n")
            Console.WriteLine("\t" & strErrMsg & " Err:" & lResult & " Cmd:" & strCmd)
        End If
    End Function

    ''' <summary> 
    ''' 再生時間や動画サイズの計算時に使用する。 
    ''' </summary> 
    ''' <param name="strCmd">コマンド名</param> 
    ''' <returns>再生時間か動画サイズ</returns> 
    Private Function MciSendLengthResult(ByVal strCmd As StringAs Integer
        ' バッファー 
        Dim strBuf As String = New String(" "c, 255)
        mciSendString(strCmd, strBuf, strBuf.Length, 0)

        ' 再生時間か動画サイズを取得 
        Return Integer.Parse(Val(strBuf).ToString())
    End Function

    ''' <summary> 
    ''' プレイヤーをOPENする。 
    ''' </summary> 
    ''' <param name="strFullPath">ファイルを再生するフルパス</param> 
    Public Sub Open(ByVal strFullPath As String)
        Me.SendString(String.Format("open ""{0}"" alias MySound", strFullPath))
    End Sub

    ''' <summary> 
    ''' playコマンドを行う 
    ''' </summary> 
    ''' <param name="strAlias">エイリアス名</param> 
    Public Sub Play(ByVal strAlias As String)
        Me.SendString(String.Concat("play ", strAlias))
        Me.SendString(String.Concat("set ", strAlias, " time format milliseconds"))
        Me.SendString(String.Concat("status ", strAlias, " length "))
    End Sub

    ''' <summary> 
    ''' プレイヤーを終了する 
    ''' </summary> 
    ''' <param name="strAlias">エイリアス名</param> 
    Public Sub PlayerStop(ByVal strAlias As String)
        Me.SendString(String.Concat("stop ", strAlias))
        Me.SendString(String.Concat("close ", strAlias))
    End Sub

#End Region

End Class
投稿者 葉月  (社会人) 投稿日時 2009/11/15 16:34:16
以下の間違いを訂正します。

■正
>>>Form1.vb

■誤
>>>Form1.cs

投稿者 (削除されました)  () 投稿日時 2009/11/16 07:18:00
(削除されました)
投稿者 winvis  (学生) 投稿日時 2009/11/16 07:52:53
ご回答ありがとうございます。
ソースコードまで載せてもらい誠にありがとうございます(>_<)