簡単なMP3プレーヤーを作っています

タグの編集
投稿者 KEN  (小学生) 投稿日時 2009/10/7 05:22:03
現在VB2008でMp3プレーヤーを作っています。
まず最初のところで
Private strFolder As String = " "
    Private strFileName As String = ""
    Dim gg As String
    Dim ff As String


    Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
いろいろ宣言しました。
ここの gg ではファイルの場所を保存する為に使います。
もう一つのff は ファイル名を保存する為に使います。
(初心者なのでまったくこれでいいのかはわかりませんが)
ファイルを開く というボタンを作ったら、
        gg = "" '初期化する
        ff = "" '初期化する

        If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.Cancel Then Exit Sub
        gg = System.IO.Path.GetDirectoryName() ’ここと
        ff = System.IO.Path.GetFileName() 'ここの()
        Label1.Text = ff
こんな感じにしました。
最初に gg と ff を初期化しました。
こんな感じでいいのでしょうか?
でも、このまま
        gg = System.IO.Path.GetDirectoryName()         
ff = System.IO.Path.GetFileName() 
のカッコの中になにも入れないとエラーになってしまいます。
何をいれればいいのでしょうか?

※全くの初心者です。
投稿者 neptune  (社会人) 投稿日時 2009/10/7 06:34:28
すみませんが、あまり良く見てないです。

取りあえずmciSendString の宣言は
http://www.pinvoke.net/search.aspx?search=mciSendString%20&namespace=[All]

>のカッコの中になにも入れないとエラーになってしまいます。
GetDirectoryName、GetFileNameのそれぞれにそこにカーソルを持っていって
F1を押すとHelpがでますから先ずはそこを見て下さい。
投稿者 るきお  (社会人) 投稿日時 2009/10/7 21:25:47
OpenFileDialogでユーザーが選択したファイルを指定するには、OpenFileDialogを使用します。

例(未確認なのでスペルミス等あるかもしれません。ヘルプもない環境でつらい…です。)
   [VB2009] 
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.Cancel Then Exit Sub

Dim FileName As String
FileName = OpenFileDialog1.FileName

MsgBox "選択されたファイルは→" & FileName

'フォルダ名とファイル名に分けるには 
gg = System.IO.Path.GetDirectoryName(FileName) ’ここと
ff = System.IO.Path.GetFileName(FileName) 'ここの() 



要するにPathクラスとOpenFileDialogクラスは勝手には連動してくれず、連動が必要であれば自分でこの2つのクラスを使って何かする必要があります。
上記の例ではFileName変数を介して目的を達成しています。

.NETの世界ではこのようにクラスごとの役割が明確に決まっており、クラス同士を組み合わせてプログラムしていくことになります。
投稿者 KEN  (小学生) 投稿日時 2009/10/8 01:12:41
>NepTuneさん

    Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
  
で宣言してありましたが、これでも大丈夫でしょうか?
>るきおさん
エラーはありませんでした。
ありがとうございます。

あと、
Button2.Clickで音楽を再生するようにしたくて、

    Call mciSendString("play """ & gg & """", "", 0, 0)
としたのですが、音楽が流れてくれません・・・

どうしたらいいでしょうか?
投稿者 KEN  (小学生) 投稿日時 2009/10/8 01:19:41
Call mciSendString("play """ & gg & """", "", 0, 0)
のggをFileNameにしたら再生されました。
無事にLabel1にもffに保存したファイル名が表示されました。

ありがとうございます。
投稿者 KEN  (小学生) 投稿日時 2009/10/8 01:23:20
ボタン3は一時停止にしていて、
Call mciSendString("pause """ & FileName & """", "", 0, 0)
というコードで動かしているんですけど、一時停止されません。
ボタン4は停止ですが、停止されません。
        Call mciSendString("close """ & FileName & """", "", 0, 0)
どうしてですか?
投稿者 KEN  (小学生) 投稿日時 2009/10/8 01:32:31
さらに質問するんですけど、
VBで一時停止しておいて「再生」を押すと最初からになりますよね。
どうすればいいでしょうか?
)

あと、このフォームを閉じたときに音楽を停止するようにするには、
コントロールボックスをFalseにして、閉じるボタンを作成して、
「停止」イベントを実行してMe.Closeで終わればいいんですよね?


たくさん質問してすいませんでした。
投稿者 neptune  (社会人) 投稿日時 2009/10/8 02:50:34
>で宣言してありましたが、これでも大丈夫でしょうか?
KEN さんの宣言はどこを参考にしたのか知りませんが、VB6のものです。
VB2008では大丈夫じゃないからAPI宣言を書いている所のアドレスを紹介しました。
説明するのは大変なので情報を貼り付けておきます。

C言語でのmciSendStringの定義
MCIERROR mciSendString(
  LPCTSTR lpszCommand,  // コマンド文字列
  LPTSTR lpszReturnString,  // 情報を受け取るバッファ
  UINT cchReturn,       // バッファのサイズ
  HANDLE hwndCallback   // コールバックウィンドウのハンドル
);

「C 言語の一般的なデータ型とそれに対応する Visual Basic のデータ型の一覧」
http://winofsql.jp/VA003334/Cprog011103012328.htm

先のAPI宣言のリンク先の内容。
Declare Ansi Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
(ByVal command As String, ByRef buffer As StringBuilder, _
ByVal bufferSize As Integer, ByVal hWndCallback As IntPtr) As Integer


整数型 (Integer) (Visual Basic 6.0 ユーザー向け)
http://msdn.microsoft.com/ja-jp/library/7f5ztkz3.aspx 
VB6のLongは32 ビット、符号付き
VB2008のLongは64 ビット、符号付き
です。
サイズが違うんです。これは重大な問題で、偶然エラーにならなかったのかも。

VB6のLongはVB2008ではIntegerに該当します。
hWndCallback はコールバックウィンドウのハンドルですからVB2008ではIntPtrに該当します。

私は大昔ここを参考にしました。・・・忘れましたけど。^ ^;
「マルチメディア自由自在! 高レベルMCIを使う 」
ゆっくり読んで下さい。
投稿者 neptune  (社会人) 投稿日時 2009/10/8 07:20:08
ごめんなさい。

リンク忘れてました。

マルチメディア自由自在! 高レベルMCIを使う
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/mci/
その他ググルと沢山サンプルがあると思います。

ついでに書いておくとmciSendCommandってのもあります。MCI文字列ではなく
MCIコマンドを送るものです。
http://msdn.microsoft.com/ja-jp/library/cc410493.aspx

これもググルと沢山サンプルがあります。C言語が多いみたいですがVBのもあります。

先ずは「マルチメディア自由自在! 高レベルMCIを使う」を一通り読むことをお勧めします。
両方の関数に関してかいてます。個人的にはmciSendCommandが判りやすかったと思います。
・・・忘れてますけど。
投稿者 (削除されました)  () 投稿日時 2009/10/8 08:12:12
(削除されました)
投稿者 葉月  (社会人) 投稿日時 2009/10/8 08:22:01
KENさん、初めましてよろしくお願いします。

>一時停止しておいて「再生」を押すと最初からになりますよね。
>どうすればいいでしょうか?
'strAlias引数には、MySoundなどエイリアスタイプを指定してください。

''' <summary> 
''' 再生を再開する。 
''' </summary> 
''' <param name="strAlias">再生するタイプ</param> 
Public Sub GetResume(ByVal strAlias As String)
Me.SendString(String.Concat("resume ", strAlias))
End Sub

>>>neptuneさん
>サイズが違うんです。これは重大な問題で、偶然エラーにならなかったのかも。
おひさしぶりです。
私が確認しているのは、uintとintで比較を行った場合、==だと問題なく通りますね。
Equalsメソッドだと通らないのでいいのですが、==で比較する方は気をつけた方がいいですね。
投稿者 KEN  (小学生) 投稿日時 2009/10/8 21:08:16
葉月さん 宜しく御願いします。

自分でボタンを作成してやるのは難しいと思ったので、
方針を変えて
Windows Media Playerを使ってやろうと思うんですが、
これではどうやってファイルを選択するのか全くわかりません。

教えていただけませんか?


投稿者 るきお(管理者)  (社会人) 投稿日時 2009/10/8 21:32:16
こんにちは。
回答ではありません。

>Windows Media Playerを使ってやろうと思うんですが、
>これではどうやってファイルを選択するのか全くわかりません。

>教えていただけませんか?
方針転換されるのはよいのですが、
いままでの流れがわかりにくくなっているのでいったんまとめていただけませんか?

やりたいことのうち、この一連のやりとりで、
何が解決して、
何が未解決なのか。
解決したものについてはどうやって解決したのか。
という点をフィードバックしてほしいです。

この掲示板も含めて技術的な掲示板の多くは
①問題を抱えている人を支援するためにあるだけではなく、
②後からGoogleなどで検索してこのページにたどり着いた人が参考になる情報を残すためにあります。

現状だと①の方は活発に投稿されていますが、②の方の情報が少ないです。
ですのでフィードバックをお願いしたいと思います。

フィードバックしてから次の質問をしてくださいというつもりはまったくなく、
この調子で質問・投稿を続行されるのはOKです。
別途フィードバックの投稿もご検討をお願いします。
投稿者 KEN  (小学生) 投稿日時 2009/10/8 21:41:22
>るきお さん
わかりました。


今までのことをまとめますと、

最初は自分でボタンなどを追加していって再生・一時停止などを作っていきましたが、停止などが上手く行かなくなりました。
そこまでは、

なのでWindows Media Player という .COMのアイテムを追加しました。

それで、Windows Media Playerの使い方がわからなくなって、ここで質問させていただきました。
投稿者 neptune  (社会人) 投稿日時 2009/10/8 22:03:44
マルチメディア自由自在! 高レベルMCIを使う
は読んだのかなぁ?

基本的なことは殆ど書いていると思うんだが。
読んでから判らんところを聞いた方がアドバイスもらいやすいですよ。

すぐにコードを求めたら、とたんにアドバイスは減ります。
投稿者 KEN  (小学生) 投稿日時 2009/10/8 23:05:08
マルチメディア自由自在! 高レベルMCIを使う
は読んだんですけど、
cboSound
がどこで宣言してあるのか全くわかりません。


これってVB6ですか?
投稿者 neptune  (社会人) 投稿日時 2009/10/8 23:27:01
>cboSoundがどこで宣言してあるのか全くわかりません。
これは図2のコンボボックスのオブジェクト名ですね。
IDEのプロパティウィンドウで設定したんでしょう。

>これってVB6ですか?
そうです。ですが、APIの使い方そのものは同じです。
投稿者 KEN  (小学生) 投稿日時 2009/10/11 05:29:27
マルチメディア自由自在! 高レベルMCIを使う
を読んでもわからなかったのでおたずねします。


再生・停止は出来ました。
しかし、一時停止はできません。

     Call mciSendString("pause """ & FileName & """", "", 0, 0)
        Button2.Text = "再開"
        Label1.Text = FileName & "を一時停止しました"
「一時停止」というボタンには上のようなコードを追加して、
        If Button2.Text = "再開" Then

            Call mciSendString("resume " & FileName & """", "", 0, 0)


            Me.Button2.Text = "再生"
                'ここになにを入れるのかわかりません               
        Else

            Call mciSendString("play """ & FileName & """", "", 0, 0)


            Label1.Text = FileName & "を再生中"
        End If
このように「再生」(再開)ボタンを作りました。

「一時停止」を押すと、音楽が停止して「再生」というボタンが「再開」にはなるのですが、その後がわかりません。

マルチメディア自由自在! 高レベルMCIを使う
では

            Call mciSendString("resume " & FileName & """", "", 0, 0)


このようになっていました。

「再開」ボタンを押しても、「再開」が「再生」になるだけで、音楽が再開されません。

どうすれば再開してくれるでしょうか?
投稿者 neptune  (社会人) 投稿日時 2009/10/11 08:44:49
すみません。なんかややこしいので

再現できるように現状出来ているコードと同じやり方で
最小限のコード

再生・停止ボタン
再生」(再開)ボタン
のみのコードをUPしてくれませんか?

音楽ファイルは自分で用意できます。
投稿者 KEN  (小学生) 投稿日時 2009/10/12 01:10:48
Button2 = 再生
Button4 = 停止
Button3 = 一時停止
再生ボタンのコード
 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        If Button2.Text = "再開" Then

            Call mciSendString("resume " & FileName & """", "", 0, 0)


            Me.Button2.Text = "再生"
            Label1.Text = FileName & "を再生中"
        Else

            Call mciSendString("play """ & FileName & """", "", 0, 0)


            Label1.Text = FileName & "を再生中"
        End If

停止ボタンのコード
       Call mciSendString("Close """ & FileName & """", "", 0, 0)
        Me.Label1.Text = FileName & "を停止しました"
        Me.TextBox1.Text = ""
一時停止のコード
        Call mciSendString("pause """ & FileName & """", "", 0, 0)
        Button2.Text = "再開"
        Label1.Text = FileName & "を一時停止しました"


    End Sub
投稿者 neptune  (社会人) 投稿日時 2009/10/12 18:50:55
本当にこれで肝の所はもれなく書いているんですね?

そうならopenしてませんね。
openをキチンとしてエイリアスをきちんと指定してみましょう。

第一引数の書式はopenでエイリアスを指定するなら
openは
"open ファイルのフルパス alias エイリアス名"
pauseは
"pause エイリアス名"
resumeは
"resume エイリアス名"

動かない場合はmciGetErrorStringで何らかのエラーメッセージが出ているかどうかのチェックもしましょう。

ちなみに私は上記でwavファイルで検証しましたが、すべて正常に動きました。

解決したならどういうコードで解決したかキチンと報告しておいてください。
掲示板の存在意義は↑にあります。
後に検索する人の為に give and take で助け合いましょう。
投稿者 KEN  (小学生) 投稿日時 2009/10/14 02:14:51
>>neptuneさん
>そうならopenしてませんね。
openっていうのはどういうことですか?
ファイルを開くことですか?
投稿者 るしぇ  (社会人) 投稿日時 2009/10/14 02:38:47
> openっていうのはどういうことですか?
open コマンドでしょ?
エイリアス指定で全部書き直せば良いのでは?

それも含めて全部説明してくれているように見えますが?
もう一度読み直してみては。
投稿者 KEN  (小学生) 投稿日時 2009/10/14 02:42:13
全部書き直したら出来ました。
ありがとうございます。
>解決したならどういうコードで解決したかキチンと報告しておいてください。
下のようなコードでできました、
Public Class Mp3プレーヤー

    Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
    Declare Function sndPlaySound _
    Lib "winmm.dll" Alias "sndPlaySoundA" _
    (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
    Public Const SND_SYNC = &H0
    Public Const SND_ASYNC = &H1
    Public Const SND_NODEFAULT = &H2
    Public Const SND_MEMORY = &H4
    Public Const SND_LOOP = &H8
    Public Const SND_NOSTOP = &H10
    Dim FilePath = FileName
    Dim FolderName As String
    Private aliasName = gg
    Dim FileName As String
    Private strFolder As String = " "
    Private strFileName As String = ""
    Dim gg As String
    Dim ff As String
    Dim aa As String
    Dim fm As String
    Dim cmd As String



    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'再生・再開
   

     Call mciSendString("play """ & FileName & """", "", 0, 0)


        Label1.Text = FileName & "を再生中"
        Button2.Text = "再生"

ELSE
   Call mciSendString("play """ & FileName & """", "", 0, 0)


        Label1.Text = FileName & "を再生中"
    
    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
’停止    
    Call mciSendString("Close """ & FileName & """", "", 0, 0)
        Me.Label1.Text = FileName & "を停止しました"
        Me.TextBox1.Text = ""

    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
’一時停止       
 Call mciSendString("pause """ & FileName & """", "", 0, 0)
        Button2.Text = "再開"
        Label1.Text = FileName & "を一時停止しました"

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
’ファイルを開く
       

        If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.Cancel Then Exit Sub


        FileName = OpenFileDialog1.FileName

        'フォルダ名とファイル名に分けるには 
        gg = System.IO.Path.GetDirectoryName(FileName) 'ここと
        ff = System.IO.Path.GetFileName(FileName) 'ここの() 

        Select Case IO.Path.GetExtension(filePath)
            Case ".avi", ".wmv"
                VideoPlay.AxWindowsMediaPlayer1.URL = filePath
            Case Else
                MessageBox.Show(FileName & "が開かれました")
        End Select


    End Sub


ちなみにmp3なども認識しました。
(VB6のコードらしいですが、VB2008でもうごきました。)
    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
'閉じるイベント       
 Call mciSendString("Close """ & FileName & """", "", 0, 0)
        Me.Close()

    End Sub
End Class
投稿者 るしぇ  (社会人) 投稿日時 2009/10/14 02:54:55
>(VB6のコードらしいですが、VB2008でもうごきました。)
ダメですよ、これ。

VB6 と VB.NET 以降で Long → Integer をはじめ宣言部が変わります。
VB.NET の宣言で書き直してください。メモリ上のサイズが変わっているので
宣言部を間違うと PC のメモリで、想定外のエリアを書き潰して壊す場合が
あります。

API は特に慎重に扱う必要がある技術です。
パソコンが動かなくなっても気にしない人なら言っても無駄かもしれませんが。
投稿者 るしぇ  (社会人) 投稿日時 2009/10/14 03:06:23
あれ?しかも open コマンド使ってないように見える。。。
URL指定でうまくいくようになったの?
エイリアスを決めて共通のオブジェクトを使用しないから
うまくいってないのかと思ってましたが。

…なんか普通に近いうちにパソコン自体を壊しそうね^^;
投稿者 neptune  (社会人) 投稿日時 2009/10/14 08:08:44
るしぇさんもおっしゃってますが、
>>(VB6のコードらしいですが、VB2008でもうごきました。)
>ダメですよ、これ。

私はこう書いてますよね。

整数型 (Integer) (Visual Basic 6.0 ユーザー向け)
http://msdn.microsoft.com/ja-jp/library/7f5ztkz3.aspx 
VB6のLongは32 ビット、符号付き
VB2008のLongは64 ビット、符号付き
です。
サイズが違うんです。これは重大な問題で、偶然エラーにならなかったのかも。

せっかく書いたのに。


neptune   (社会人)   投稿日時 2009/10/06 21:34:28 

投稿者 neptune   (社会人)   投稿日時 2009/10/07 17:50:34  
のリンク先見たんですかね?見たのなら
後々Logを見る人のために書いておきますが

'宣言はこうなって 
 Private Declare Ansi Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
                (ByVal command As String, _
                 ByRef buffer As StringBuilder, _
                 ByVal bufferSize As Integer, _
                 ByVal hWndCallback As IntPtr) As Integer

'mciSendString の使い方は 
        'cmdString:コマンド文字列 
       Dim ret As Integer = mciSendString(cmdString, Nothing, 0, IntPtr.Zero)

のようになると思いますよ。

それにしてもopenなしでplayを送っても自動的にopenするんだろうか?
再生はするんですけどね。
エイリアスを使わないならそれでも良いかも知れないが動作を把握してからの方が安心。
Helpに書いてある定石って大事ですよ。