質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

FlaskでRedirect(url_for('index')) の呼び出しが正常に動作しない

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 204

akeyi

score 0

前提・実現したいこと

Flaskで音楽ファイルを再生するシステムを作っています。
音楽再生開始後にPLAYボタンを無効にし、
再生完了後にPLAYボタンを有効にする機能を実装中に
以下の問題が発生しました。

目的は、「再生完了時にPLAYボタンが再び有効にしたい。」

発生している問題・再生完了のcallbackメッセージまで問題ないですが、

下記の該当ソースでredirect部分が正常に動作しません。(呼び出されない)

^C(venv) pi@raspberrypi:~/hello_flask/sound $ python fl_play_all_format.py
 * Serving Flask app "fl_play_all_format" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 237-014-604
[2020-07-21 22:34:22,521] INFO in fl_play_all_format: 1
192.168.0.108 - - [21/Jul/2020 22:34:22] "GET /1 HTTP/1.1" 200 -
192.168.0.108 - - [21/Jul/2020 22:34:28] "POST /showfile HTTP/1.1" 200 -
Finish
[2020-07-21 22:34:44,024] INFO in fl_play_all_format: callback

該当のソースコード

ソースコード
def wrap_play(filename):
    snd = mpxplayer(filename)
    re = snd.run()
    app.logger.info("callback")
    return redirect(url_for("index", val=1), code=307) #ここが正常に動作しない

試したこと(Pythonソース全体)

from flask import Flask, render_template, request, redirect, url_for
from MPXPLAYER import mpxplayer
from multiprocessing import Process
import glob

app = Flask(__name__)

def getmusicInfo():
    list = {}
    cnt = 0
    for file in glob.glob("/mnt/samba/*.mp*"):
        list[cnt] = file
        cnt = cnt + 1
    return list

@app.route("/<val>")
def index(val):
    app.logger.info(val)
    val = int(val)
    return render_template("mpindex.html", flag = val, selectedval = 0,
                            musiclink=getmusicInfo())

def wrap_play(filename):
    snd = mpxplayer(filename)
    re = snd.run()
    app.logger.info("callback")
    return redirect(url_for("index", val=1), code=307)

@app.route("/showfile", methods=['GET','POST'])
def main():

    wavFile= 0

    global play
    if request.method == 'POST':
        if request.form['bt'] =='PLAY':
            wavFile = str(request.form["musicfile"])
            musicFile = getmusicInfo()[int(wavFile)]
            play = Process(name="play", target=wrap_play, args=(musicFile, ))
            play.start()
            return render_template("mpindex.html", flag = 0, selectedval = int(wavFile),
                            musiclink=getmusicInfo())

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0')

補足情報(HTMLソース)

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
  </head>
  <body>
    <div class="container">
      <div class="header">
        <h3 class="text-muted">Music Page</h3>
        <form action = '/showfile' method='POST'>
          <select name="musicfile" style="font-size:16px;" id="listbox">
          {% for key, value in musiclink.items() %}
            {% if selectedval == key %}
               <option value = "{{key}}" selected>{{value}}</option>
            {% else %}
               <option value = "{{key}}" > {{value}}</option>
            {% endif %}
           {% endfor %}
           </select>
           {% if flag == 1 %}
                <input type="submit" name="bt" value="PLAY" id="bt1"></input>
           {% else %}
                <input type="submit" name="bt" value="PLAY" id="bt1" disabled></input>
           {% endif %}
        </form>
<script type="text/javascript" language="javascript">
         var select = document.getElementById( 'listbox' );
          select.onchange = function(){
          document.getElementById("bt1").disabled = false;
          }
</sciprt>
      </div>
    </div>
  </body>
</html>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

動かせないので推測ですが、main()の処理はreturn render_template()で終了しているように見えます。
その後、wrap_play()でredirectされても、HTTP通信は終わっているはずなので、送り先がないのではないでしょうか。

なので、wrap_play()でredirectを呼ぶのではなく、フロント側でwrap_play()を呼ぶようなajax処理を実装するか、<val>の切り替え処理をセッション(クッキー)に保持させてそちらを確認するようにするかしてはいかがでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る