MPEG3の音楽ファイルを読み込んで鳴らそうとしているのですが、
うまくいきません.
サーバー(同一システム)上でブラウザを開く分には動作するのですが、
ローカルネットワークでつながった他のシステムからは動作しません。
何がおかしいのでしょうか?
1.以下のようにしてみました
Response.ContentStream := TFileStream.Create(FileName, fmOpenRead);
Response.ContentType := 'audio/mpeg';
2.次に以下のようにしてみました
FileStream := TFileStream.Create(FileName, fmOpenRead);
Response.CustomHeaders.Add(Format('filename="%s"', [FileName]));
Response.ContentType := 'audio/mpeg';
Response.ContentStream := FileStream;
Response.SendResponse;
FileStream.Free;
上記とも動作しません。
よろしくお願いします.
content-typeに関連付けされたソフトが起動するはずです。
関連付けによっては、ファイルをすぐに開かずに、ダウンロードを促す場合もあります。
ローカルの環境によります。
にしのさんいつもありがとうございます.
ソフトはWindowsMediaPlayerが起動します。
もちろんMP3ファイル自体直ではWindowsMediaPlayerで
再生できます。
現状では、ダウンロードが(WMPのメーターが動いた状態)がしばらく
つづき、『不明なエラーが検出されました.』とでます。
ヘルプボタンを押して参照すると
『Error# C00D11CD
Sorry, no more help is available for this problem at this time.』
と表示されます。
WWWサーバーは『AnHTTPD』を使用しているのですが、
この後はページを開くことができない状態になります。
『AnHTTPD』がフリーズし、『AnHTTPD』を再起動しなければ
ならない状態になります。
何となく、anhttpdが問題のような気がします。
Apacheなど、別のhttpdで試してみてください。
サーバーの問題にしろクライアントの問題にしろ
サーバーのテストをセーフティにするには
80番以外のポートを使うと良いと思います。
で再生側ですがMP3のファイルサイズがそんなに大きくないのなら
テンポラリーファイルを作ってダウンロードして
それを再生すると言う形で試すと
サーバーの仕様の制限はすくなくなります。
このケースだと再生側ソフトはdelphiならば
メディアプレーヤーコンポーネントでも再生可能です。
(Windows APIなので特許ライセンスの問題もなし)
テンポラリーファイルはアプリケーションのサブディレクトリー内に作り
起動時ないしは必要に応じて削除すれば
不正終了時などでもゴミが残らなくなります。
とりあえずファイルがダウンロードできるかどうかテストすることで
どこに問題があるか切り分けしやすくなるのではないかと思います。
以下画像の場合とMP3の場合ですが
画像はOKですが、MP3はだめなのです。
procedure TWebModuleTest.WebModuleTestWebActionItemMainAction(
Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
Response.Content := '<IMG SRC=TestHPSource.dll/load>';
end;
procedure TWebModuleTest.WebModuleTestWebActionItemLoadAction(
Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
FileStream: TFileStream;
FileName: string;
begin
//画像のファイル名
FileName := 'E:\WWW\HomePage\Sample.jpg';
//ファイルストリームの生成
FileStream := TFileStream.Create(FileName, fmOpenRead);
try
//レスポンスの設定
Response.ContentType := 'image/jpeg';
Response.ContentStream:= FileStream;
Response.SendResponse;
finally
FileStream.Free;
end;
end;
procedure TWebModuleTest.WebModuleTestWebActionItemMainAction(
Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
Response.Content := '<EMBED SRC=TestHPSource.dll/load>';
end;
procedure TWebModuleTest.WebModuleTestWebActionItemLoadAction(
Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
FileStream: TFileStream;
FileName: string;
begin
//画像のファイル名
FileName := 'E:\WWW\HomePage\Sample.mp3';
//ファイルストリームの生成
FileStream := TFileStream.Create(FileName, fmOpenRead);
try
//レスポンスの設定
Response.ContentType := 'audio/mp3';
Response.ContentStream:= FileStream;
Response.SendResponse;
finally
FileStream.Free;
end;
end;
たぶん、「画像を表示するには?」に続く問題だと思われますので、
> で再生側ですがMP3のファイルサイズがそんなに大きくないのなら
> テンポラリーファイルを作ってダウンロードして
> それを再生すると言う形で試すと
> サーバーの仕様の制限はすくなくなります。
この手段は使えませんね。そうすると、「画像を表示するには?」の問題に戻りますから。
また、
> サーバーの仕様の制限はすくなくなります。
であるならば、
> とりあえずファイルがダウンロードできるかどうかテストすることで
は必要ないと思います。
これが必要なのは、
・作成するのはサーバ。あるブラウザで、そのサーバからダウンロードできるかどうかを試す。
・作成するのはブラウザ。そのブラウザで、あるサーバからダウンロードできるかどうかを試す。
の2通りだけだと思います。
XOOXさんはご存じだと思いますが、ダウンロードは、どのファイルでも同じです。content-typeの違いと、サーバの実装によってはバイナリとアスキーの違いだけです。ISAPIの動作は関係ありません。
ただ、
> どこに問題があるか切り分けしやすくなるのではないかと思います。
この切り分けは必要と思います。
ダウンロードでなく、単純にそのファイルをクライアントPCで再生できるのでしょうか。
そのMP3をデコードできなくてエラー、ということも考えられますので。
ファイル自体は正しくて、クライアントPCでも再生できる前提で、
今回の場合、ISAPI側からみた、MP3ファイルの出力で、ファイルが再生されない(そしてanhttpdがフリーズ)、というのが問題なので、
原因は、
1.サーバの不具合
2.ブラウザの不具合
3.ISAPIの不具合
だと思います。
このうち、1と3を試すため、apacheなどの他のhttpdを使用してくださいと書きました。
もし、apacheで正しく動作したならば(確実とは言えませんが)、anhttpdの不具合と言えるでしょう。
apacheでも正しく動作しない場合、ないとは思いますが、他のブラウザで試すことをしてみます。
これで、どのブラウザでも、どのサーバでも不具合が出るようでしたら、ISAPIの不具合と言えます。
ISAPIの不具合とわかったら、次にサーバの動作を、HTTP/1.1から、HTTP/1.0にしてみます。
もし、1.1で動かなくて、1.0で動けば、その差異を検証していけば具体的なバグに近づけると思います。
httpd-2.0.47-win32-src.zipをダウンロードして
解凍まではしたのですがそこから先まったくわかりません。
このファイルでいいのかもわかりませんが....
なにしろ英語はちんぷんかんぷん。
だから、Appachには今まで一切指一本触れてなかった
状態なんですけど...
実行ファイルも見当たらないし。
設定もわかりませんし、
まる一日ネットをまわったものの情報すら得られない状態です.
Appachの使い方を教えていただけませんか?
もしくは、インストールや設定ほうほうがかかれている
日本語のサイトなどの紹介をおねがいします。
# アパッチの綴りは、apacheです。
どうやって検索しています?
googleなどで検索すれば、すぐに見つかると思いますが。
apache インストール win32
というキーワードですぐ見つかりましたよ。
窓の杜などでもダウンロードできますし。
それと、httpd-2.0.47-win32-src.zipは、ファイル名からしてソースファイルとわかると思います。
Windows版をコンパイルするには、VisualC++、gccなどのC/C++コンパイラが必要です。
# もしかしたらBorland C++ Compiler5.5でもOKかも
gccの場合、makeなどのツールも必要となります。
ソースからコンパイルする必要がなければ、バイナリのほうをダウンロードした方が簡単です。
なんとか、インストールができたようです.
次に
C:\Program Files\Apache Group\Apache2\htdocs
このディレクトリの下に
subdir
フォルダを作成し、DLLを掘り込んだのですが
DLLが実行しません。
設定を調べてみたのですが、やはりわかりません。
いろいろやってみましたが、どうしてもできません。
Appacheって動作させるのって非常に困難なようです.
動作するようにするにはどうすればよいのでしょうか?
困難というほどでもないと思いますよ。
設定が多いだけで、難しい物ではありません。
初期状態では、Apacheをインストールしたディレクトリのcgi-binが、実行可能に設定されています。
# こちらの環境ではD:\Apache2\cgi-binなので、これで説明します
まず、httpd.confを修正します。
LoadModule isapi_module modules/mod_isapi.so
という行がコメントされていないことを確認してください。
半角のシャープ記号から始まっていれば、コメントアウトされているので、シャープを消してください。
次に、
ScriptAlias /cgi-bin/ "D:/Apache2/cgi-bin/"
という行を確認してください。
D:\Apache2/cgi-binは、こちらの環境なので、違うはずです。
# こちらと同じにする必要はありません
ScriptAliasは、cgiなどを実行するために必要なエイリアスを切るものです。
次に、
<Directory "D:/Apache2/cgi-bin">
という行があると思います。ScriptAliasで指定してあったディレクトリがかかれていると思います。
この行の「上に」、
AddHandler isapi-isa .dll
を追記してください。
さらに、
<Directory "D:/Apache2/cgi-bin">
のすぐ下(2行目くらい)にある、
Options None
をコメントアウトし、
Options ExecCGI
としてください。
これで動くはずです。
Delphiから少しはずれましたが、このあたりはApacheのメーリングリストの過去ログなどを調べればわかります。
次はがんばってください。
なんどもすみません。
DLLは実行しようとしたようですが
以下のメッセージがでます。
Widowsではパーミッションの設定ってないと思うのですが。
Delphiに関係なくすみません.
メーリングリストの過去ログというのは
http://www.jajakarta.org/ml/general/
のことですか?
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
Forbidden
You don't have permission to access /TestHPSource.dll on this server.
--------------------------------------------------------------------
Apache/2.0.47 (Win32) Server at kitajima Port 80
上の記述でできるはずです。
もっと調べましょう。
わからなければ、anhttpdのバグが解消されるまで待った方がよいと思います。
ここはdelphiの掲示板ですので。
にしのさん、すみませんでした。
話をDelphiに戻します。
Response.Content := '<A HREF="Data.ASX">開始</A>';
"Data.ASX"の中身
<ASX Version = "3.0">
<Entry><Ref href = "E:\WWW\HomePage\Data.MP3"/></Entry>
</ASX>
上記の状態では動作します。
Response.Content :=
'<ASX Version = "3.0">' + #13#10 +
' <Entry><Ref href = "E:\Data\Data.MP3"/></Entry> + #13#10 +
'</ASX>';
これは動作しませんでした.
そこで質問なのですが
1.このままだと《URL:http://.../Data.ASX》で実行されてしまいます。
直接実行されないようにするにはどうすればよいのでしょうか?
目的は下記のとおりです。
2.前回のように、すべてのデータをTStreamに読み込んで
SendResponseでWebモジュールに渡す場合には
呼び出せないと認識しているのですが、それでよいのでしょうか?
もちろんデータファイルが保存されているディレクトには
仮想パスの設定等は行っていません.
3.書き目的を達成するのに効率の良い方法等はありませんか?
目的:HPは基本認証を行っているので、ユーザー名から入った人の情報が
わかるようになっており、配信ファイルを配信する場合には、
誰が、どのファイルをいつ見たかのログを取りたい。
そのため、直接受け取れないようにしたい。
済みませんがよろしくお願いします.
<ASX Version = "3.0">
<Entry><Ref href = "E:\WWW\HomePage\Data.MP3"/></Entry>
</ASX>
と、
Response.Content :=
'<ASX Version = "3.0">' + #13#10 +
' <Entry><Ref href = "E:\Data\Data.MP3"/></Entry> + #13#10 +
'</ASX>';
では、指定しているファイルが全く違うのでは?
Response.Content :=
'<ASX Version = "3.0">' + #13#10 +
' <Entry><Ref href = "E:\WWW\HomePage\Data.MP3"/></Entry> + #13#10 +
'</ASX>';
こうだった場合はどうなります?
これでうまく動けば、単純にファイルの指定ミスです。
2は、Stream渡しできます。
ちなみに、Streamで渡せないデータはありません。テキストだろうがバイナリだろうが、Streamで流すことができます。
できないのは、Redirect処理だけですね。これも、ヘッダを直接書けばできるかもしれません。
3は、単純に考えれば、
呼び出し元ページを限定(例:download.html)。
download.htmlから、*.asxを出力するCGIを呼び出し。
# このCGIは、download.htmlからしか呼べなくする(Refererをチェック)
*.asxのref指定に、MP3を読み込み出力するCGIを用意。
# このCGIは、asxから読み出す場合のみ有効。
こうでしょう。
セッション管理もしてあれば、管理しているセッションであれば有効、とすることもできます。
asxの仕組みを知らないので、どう実現するかはわかりません。
# これは一般的な方法です
それぞれのCGIで、
ユーザ名、アクセス時間、対象ファイル、その他の情報
をログに吐けばよいかと思います。
にしのさん、説明不足でどうもすみません。
Data.ASXというファイル名のテキストファイルに以下のように書いたものを
用意し、URLパスのとおっている場所に保存します.
この場合仮想パスが設定されていれば「E:\Data\Data.MP3」の部分を
「http://〜」に設定することができます。
--------------------------------------------------------------------
<ASX Version = "3.0">
<Entry><Ref href = "E:\Data\Data.MP3"/></Entry>
</ASX>
--------------------------------------------------------------------
そして、以下のようにContentを返して表示されたウェブページで
開始をクリックするとWMPが起動しData.MP3が再生します。
--------------------------------------------------------------------
Response.Content := '<A HREF="Data.ASX">開始</A>';
--------------------------------------------------------------------
直接 Response.Content に Data.ASXの中身である「<ASX 〜」のコードを
記入して渡しても、実行がされなかった、と言う意味です。
この場合表示されているWebページのソースを表示をすると
中身は Data.ASX と同じものになっていました.
「<ASX 〜」のコードはHTMLとは関係ないということでしょうか?
それから、2の質問は、
通常は「http://.../~.../Data.MP3」とかで再生できますが、
URLパス(仮想パス="//...")の設定などしていない
ディレクトリ(ドライブ)にデータを保存しておいた場合には、
もちろんハッキングされサーバーに侵入されれば別でしょうけど。
クライアントからはそのデータを差すURLが指定できない?から
IE等より再生することができないんじゃないのかなという質問です。
最後に3つめの質問の回答からですが、
>download.htmlから、*.asxを出力するCGIを呼び出し。
># このCGIは、download.htmlからしか呼べなくする(Refererをチェック)
つまり、*.asxというファイルをクライアントがダウンロードする都度
テンポラリファイルのような形で作成し、
読み出せばよいということでしょうか?
なんとなく、できるような気がしますのでやってみます。
ありがとうございます。
1に関して。
ちゃんと、ContentTypeは 'video/x-ms-asf'にしてありますか?
text/htmlのままであれば、例えそれがJPEGイメージだろうとも、HTMLファイルとして表示しようとしますよ。
2に関して。
サーバで動くCGIやモジュールは、クライアントから見えないファイルなどを操作することができます。
# 当たり前ですよね
CGIが、クライアントから見えないファイルを読み出して返せばよいのです。
3に関して。
Streamは、TFileStreamだけではありません。
TMemoryStreamを使えば、テンポラリファイルなどなくともStreamを用意できます。
当初の目的には到達できませんでしたが、
MP3ファイルの実行ができました.
あっ、そういえばサーバーフリーズで動作しない件でしたが
一度に読み込んだデータが大きいとおかしくなるみたいでした.
と、いうことで、ストリーミングの方法に変更したわけですが
これだとうまくいくようです.
最後に、MP3等のデータはパスがとおっているので
パスとファイル名がばれるとクライアントから
アドレスを直接書き込まれると再生してしまいます。
もう少し勉強します。
にしのさんどうもありがとうございました.
ツイート | ![]() |