C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[16]: 字幕の表示について


(過去ログ 73 を表示中)

[トピック内 17 記事 (1 - 17 表示)]  << 0 >>

■41929 / inTopicNo.1)  字幕の表示について
  
□投稿者/ motu (1回)-(2009/10/04(Sun) 18:23:59)

分類:[C#] 

失礼します。motuと申します。
今、visual C# 2008にて、
WindowsMediaPlayerに字幕を付けるといったプログラムを作成しているのですが、
デバッグの段階でエラーが発生してしまいます。

そのプログラムが以下です。

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
int i;
i=0;
//checkbox1にcheckが入ると字幕表示
if (this.checkBox1.Checked == true)
{ //WMPファイルである、axWindowsmediaPlayer1の再生時間を取得、timeにいれる。
double time = axWindowsMediaPlayer1.currentMedia.duration;
//timeに値がある限り
while (time > -1)
{
          time = axWindowsMediaPlayer1.currentMedia.duration;
          //字幕データであるdataGridView1([0,i]には時間、[1,i]にはその時間の字幕データ)に対し、適切なtimeの位置を探し出す。
if (Convert.ToDouble(dataGridView1[0, i].Value) < time && Convert.ToDouble(dataGridView1[0, i + 1].Value) > time)
{//そのとき、字幕boxのtextBox2に字幕を表示
textBox2.Text = Convert.ToString(dataGridView1[1, i].Value);
}
if (Convert.ToInt32(dataGridView1[0, i].Value) > -1)
{//もし、字幕データの末尾までいけば、再び頭から検索。
i = 0;
}
}
}
}
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
エラーは
if (Convert.ToDouble(dataGridView1[0, i].Value) < time && Convert.ToDouble(dataGridView1[0, i + 1].Value) > time)
の文に対し、

ArgumentOutOfRangeExceptionはハンドルされませんでした。
インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
パラメータ名:index

と、でてきます。

Cは扱っていましたが、C#の経験が浅く、無茶苦茶ともいえる文を書いているかもしれませんが、
どなたかエラーの解決方法か、さらによい字幕作成のアルゴリズムがあればご教授願えないでしょうか;;

引用返信 編集キー/
■41931 / inTopicNo.2)  Re[1]: 字幕の表示について
□投稿者/ gtk2k (91回)-(2009/10/04(Sun) 18:57:09)
その行にブレークポイント張ってiの値がどうなっているか調べてみれば?
引用返信 編集キー/
■41933 / inTopicNo.3)  Re[2]: 字幕の表示について
□投稿者/ motu (2回)-(2009/10/04(Sun) 19:14:19)
No41931 (gtk2k さん) に返信
> その行にブレークポイント張ってiの値がどうなっているか調べてみれば?

さっそくしらべてみたところ、
iの値は0でした。
最初の宣言のままのようにおもえるのですが、
原因はなんなのでしょうか?
引用返信 編集キー/
■41934 / inTopicNo.4)  Re[3]: 字幕の表示について
□投稿者/ motu (3回)-(2009/10/04(Sun) 19:18:40)
No41933 (motu さん) に返信
> ■No41931 (gtk2k さん) に返信
>>その行にブレークポイント張ってiの値がどうなっているか調べてみれば?
>
> さっそくしらべてみたところ、
> iの値は0でした。
> 最初の宣言のままのようにおもえるのですが、
> 原因はなんなのでしょうか?

すいません、i++;
がぬけていました;;

こんな基本的ところもできてなくてすいませんでした。

while文のラスト前にi++;を追加してみましたが、
以前同じエラーがでます。
引用返信 編集キー/
■41935 / inTopicNo.5)  Re[4]: 字幕の表示について
□投稿者/ gtk2k (92回)-(2009/10/04(Sun) 19:24:15)
2009/10/04(Sun) 19:27:32 編集(投稿者)

削除
引用返信 編集キー/
■41936 / inTopicNo.6)  Re[5]: 字幕の表示について
□投稿者/ gtk2k (93回)-(2009/10/04(Sun) 19:27:03)
i + 1 の行を見ているから、最後は i = 行数 - 2 でループが終わるべきところを
最後のループ時のiはi = 行数 - 1になっているとか?

引用返信 編集キー/
■41939 / inTopicNo.7)  Re[6]: 字幕の表示について
□投稿者/ motu (4回)-(2009/10/04(Sun) 20:24:49)
No41936 (gtk2k さん) に返信
> i + 1 の行を見ているから、最後は i = 行数 - 2 でループが終わるべきところを
> 最後のループ時のiはi = 行数 - 1になっているとか?
>

返信ありがとうございます。

gtk2kさんに言われて、もう一度確認したところ、
二行目のif
if (Convert.ToInt32(dataGridView1[0, i].Value) > -1)
の>が逆でした;;
そこで、
if (Convert.ToInt32(dataGridView1[0, i].Value) < -1)
に書き直しました。

また、iのみている行数ですが、
gtk2kさんの言うとおり
iのカウンタを戻すifよりも先に、timeを検索するifをもってきているため
Convert.ToDouble(dataGridView1[0, i + 1].Value) > time
の時点で存在していないdataGridView1のフィールドをみている可能性があるので、
iのカウンタを戻すifを先にもってきました。

さらに、timeを検索するifではConvert.ToDoubleとしているのに、
なぜか、iのカウンタを戻すifではConvert.ToInt32としていたので、
Convert.ToDoubleに統一しました。

ここで、現在はこうなりました。↓
****************************************************
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
int i;
i=0;

if (this.checkBox1.Checked == true)
{
double time = axWindowsMediaPlayer1.currentMedia.duration;

while (time > -1)
{
time = axWindowsMediaPlayer1.currentMedia.duration;
if (Convert.ToDouble(dataGridView1[0, i+1].Value) < -1)
{
i = 0;
}
if (Convert.ToDouble(dataGridView1[0, i].Value) < time && Convert.ToDouble(dataGridView1[0, i + 1].Value) > time)
{
textBox2.Text = Convert.ToString(dataGridView1[1, i].Value);
}

i++;
}
}
}
************************************************************************************
ここで、デバッグしてみたところ、
こんどは if (Convert.ToDouble(dataGridView1[0, i+1].Value) < -1)のところで

FormatExceptionはハンドルされませんでした。
入力文字列の形式が正しくありません。

とでました。
他にどこがおかしいのでしょう?
キャストの仕方がおかしいのでしょうか?
何度もすいません;;

引用返信 編集キー/
■41940 / inTopicNo.8)  Re[7]: 字幕の表示について
□投稿者/ motu (5回)-(2009/10/04(Sun) 20:43:13)
追記です。
エラー部のiをみてみたところ、8(元データの行数は8)と、最後まで回ったところでエラーがでているみたいです。
また、エラーが、

ArgumentOutOfRangeExceptionはハンドルされませんでした。
インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
パラメータ名:index

というものに変化しました。

存在しないDatagridViewをみたとき、ifでそのときをつかむには
if (Convert.ToDouble(dataGridView1[0, i+1].Value) < -1)
としてはいけないでしょうか?

ちなみにiは参照してくるデータによって変化するので、
きまった回数回すといった、iを定数にすることができません。
引用返信 編集キー/
■41941 / inTopicNo.9)  Re[8]: 字幕の表示について
□投稿者/ gtk2k (94回)-(2009/10/04(Sun) 21:01:39)
2009/10/04(Sun) 21:03:26 編集(投稿者)
たとえば、8行あったとすると
DataGridView[x,8]
とするとArgumentOutOfRangeExceptionエラーが発生する。
[]内はインデックスを指定しなければならないので、最後の行のデータを取得する場合は
DataGridView[x,7]
と指定する。
なので、ループをまわすときに
While(time > -1 And i < DataGridView.Rows.Count - 1)
{
  //処理

  i++;
}
というように行数も判定しないといけない。

引用返信 編集キー/
■41942 / inTopicNo.10)  Re[9]: 字幕の表示について
□投稿者/ motu (7回)-(2009/10/04(Sun) 21:51:47)
No41941 (gtk2k さん) に返信
> 2009/10/04(Sun) 21:03:26 編集(投稿者)
>
> たとえば、8行あったとすると
> DataGridView[x,8]
> とするとArgumentOutOfRangeExceptionエラーが発生する。
> []内はインデックスを指定しなければならないので、最後の行のデータを取得する場合は
> DataGridView[x,7]
> と指定する。
> なので、ループをまわすときに
> While(time > -1 And i < DataGridView.Rows.Count - 1)
> {
> //処理
>
> i++;
> }
> というように行数も判定しないといけない。

返信ありがとうございます。
ようやく正しい意味が理解できましたm(_ _)m
行数が8ならば、0〜7なので、以上のようにしなければならないのですね。
本当にありがとうございます。
gtk2kさんのアドバイスうけかきなおしてみたところ
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
int i;
i=0;

if (this.checkBox1.Checked == true)
{
double time = axWindowsMediaPlayer1.currentMedia.duration;

while (time > -1)
{
time = axWindowsMediaPlayer1.currentMedia.duration;
if (i == dataGridView1.Rows.Count-1)
{
i = 0;
}

if (i < dataGridView1.Rows.Count - 1)
{
if (Convert.ToDouble(dataGridView1[0, i].Value) < time && Convert.ToDouble(dataGridView1[0, i + 1].Value) > time)
{
textBox2.Text = Convert.ToString(dataGridView1[1, i].Value);
}
i++;
}
}
}
}
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
となりました。
デバッグしてみると、
エラーは出ませんでしたが、
チェックボックスにチェックするとフリーズするので、
ブレークポイントにてどの時点までいっているかをみてみました。
すると、
if (Convert.ToDouble(dataGridView1[0, i].Value) < time && Convert.ToDouble(dataGridView1[0, i + 1].Value) > time)
までうごいており、
その以下の{}の中まではいってないようです。
これは何が原因なのでしょうか。


引用返信 編集キー/
■41946 / inTopicNo.11)  Re[10]: 字幕の表示について
□投稿者/ gtk2k (96回)-(2009/10/05(Mon) 09:57:39)
[0,i].Value や[0,i + 1].Valueの値がおかしいからなのでは?
引用返信 編集キー/
■41970 / inTopicNo.12)  Re[11]: 字幕の表示について
□投稿者/ motu (9回)-(2009/10/05(Mon) 20:50:08)
No41946 (gtk2k さん) に返信
> [0,i].Value や[0,i + 1].Valueの値がおかしいからなのでは?

返信ありがとうございます。
値を確かめるために、以下のようにしてたしかめてみました。
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
int i;
double j;
string dat;
i=0;

if (this.checkBox1.Checked == true)
{
double time = axWindowsMediaPlayer1.Ctlcontrols.currentPosition;

while (time > -1)
{
time = axWindowsMediaPlayer1.Ctlcontrols.currentPosition;
if (i == dataGridView1.Rows.Count-2)
{
i = 0;
}

if (i < dataGridView1.Rows.Count - 2)
{
dat = Convert.ToString(dataGridView1[1, i+1].Value);
j = Convert.ToDouble(dataGridView1[0, i+1].Value);
//ブレークポイント
if (Convert.ToDouble(dataGridView1[0, i].Value) < time && Convert.ToDouble(dataGridView1[0, i + 1].Value) > time)
{
label2.Text = "成功";
//label2.Text = "" + Convert.ToString(dataGridView1[1, i].Value) + "";
}
i++;
}
}
}
}
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

しかし、値は特におかしいところはなく、正しく値をとれていました。
フリーズする原因は、ifのなかの、label2.textのところかとおもい、"成功"という文を表示するようにしましたが、
実行すると、"成功"は表示されず、変わらずフリーズします。
引用返信 編集キー/
■41977 / inTopicNo.13)  Re[12]: 字幕の表示について
□投稿者/ Azulean (466回)-(2009/10/05(Mon) 22:28:05)
No41970 (motu さん) に返信
> double time = axWindowsMediaPlayer1.Ctlcontrols.currentPosition;
> while (time > -1)
> {
> time = axWindowsMediaPlayer1.Ctlcontrols.currentPosition;
そもそも、time の値は変化しているのでしょうか?
そして、-1 より小さくなることはあるのでしょうか?

もし、-1 より小さくなることがないのであれば、永遠にそのループから脱出せず、フリーズしたかのように見えるかと思います。
それとも、どこかで break しているのでしょうか。
引用返信 編集キー/
■42029 / inTopicNo.14)  Re[13]: 字幕の表示について
□投稿者/ motu (11回)-(2009/10/06(Tue) 20:09:10)
No41977 (Azulean さん) に返信
> ■No41970 (motu さん) に返信
>> double time = axWindowsMediaPlayer1.Ctlcontrols.currentPosition;
>> while (time > -1)
>> {
>> time = axWindowsMediaPlayer1.Ctlcontrols.currentPosition;
> そもそも、time の値は変化しているのでしょうか?
> そして、-1 より小さくなることはあるのでしょうか?
>
> もし、-1 より小さくなることがないのであれば、永遠にそのループから脱出せず、フリーズしたかのように見えるかと思います。
> それとも、どこかで break しているのでしょうか。

Azuleanさん返信ありがとうございます。
Azuleanさんの言うとおり、永遠にループしてました;;

なので、whileの中を、
while (axWindowsMediaPlayer1.status == "再生中")
と、WMPが再生中のときのみとしたのですが
一度再生中になると先ほどのようなフリーズしたようになって
再生中から一時停止に切り替えることができません。

このループはをうまく抜けるにはどのようにしたらよいのでしょうか?
やはり、.statusはwhileの条件として適切ではないのでしょうか?

引用返信 編集キー/
■42106 / inTopicNo.15)  Re[14]: 字幕の表示について
□投稿者/ Azulean (467回)-(2009/10/08(Thu) 00:13:57)
No42029 (motu さん) に返信
> このループはをうまく抜けるにはどのようにしたらよいのでしょうか?
> やはり、.statusはwhileの条件として適切ではないのでしょうか?

ずっとループしているのが問題でしょう。
ループから抜けない限り、ボタンを押すことはできません。

故に、タイマーで定期的に処理をする等、方針を考え直してください。
引用返信 編集キー/
■42265 / inTopicNo.16)  Re[15]: 字幕の表示について
□投稿者/ motu (14回)-(2009/10/11(Sun) 01:25:59)
No42106 (Azulean さん) に返信
> ■No42029 (motu さん) に返信
>>このループはをうまく抜けるにはどのようにしたらよいのでしょうか?
>>やはり、.statusはwhileの条件として適切ではないのでしょうか?
>
> ずっとループしているのが問題でしょう。
> ループから抜けない限り、ボタンを押すことはできません。
>
> 故に、タイマーで定期的に処理をする等、方針を考え直してください。

Azuleanさん、返信ありがとうございます。
あのあと、いろいろやってみた結果
*********************************************
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
int i, time;
i = 0;
while (i < dataGridView1.Rows.Count - 2 && this.checkBox1.Checked == true)
{
time = Convert.ToInt32(axWindowsMediaPlayer1.Ctlcontrols.currentPosition);
if (Convert.ToInt32(dataGridView1[0, i].Value) < time && Convert.ToInt32(dataGridView1[0, i + 1].Value) > time)
{
textBox2.Text = "" + Convert.ToString(dataGridView1[1, i].Value) + "";
}
i++;
}
}
**********************************************
とすることで、チェックボックスをONにするたびにその時の字幕を表示することはできるようになりました。
これを元に、一秒ごとにこの処理を繰り返して、字幕を更新していくといったプログラムを作ろうとし、
timer.Interval等を使ってやってみましたが、またループにはまったりとうまくいきませんでした。

チェックボックスがONである限り、この処理を一秒ごとに繰り返すにはどのようにしたらよいのでしょうか?
引用返信 編集キー/
■42574 / inTopicNo.17)  Re[16]: 字幕の表示について
□投稿者/ motu (15回)-(2009/10/18(Sun) 17:17:33)
timerイベントを使用することで解決できました。
みなさんありがとうございます。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -