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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

976閲覧

ブラウザ上にローカルフォルダのmp3ファイルを載せたい

moukin

総合スコア5

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2022/12/07 04:58

前提

python初心者です
flaskでMubert-Text-to-musicを利用した自動作曲アプリを作っています。
gptindex.htmlからの入力で、ローカルのフォルダ(c:user/.../flaskbook)に楽曲ファイルが作成されている状況までは実装できております

実現したいこと

ブラウザ上でローカルの楽曲ファイル(ex c:user/.../flaskbook/202212071212.mp3)を再生できるようにしたい

発生している問題・エラーメッセージ

特にrender_templateを行っても画面に変化がない

該当のソースコード

python

1views.py 2 3from flask import Blueprint, render_template, request, session 4from flask_wtf.csrf import CSRFError 5 6from apps.haiku.formgpt import UploadgpthaikuForm 7from apps.haiku.mubert import mubert 8 9ha = Blueprint("haiku", __name__, template_folder="templates") 10 11 12@ha.route("/mubert", methods=["GET", "POST"]) 13def gptmu(): 14 form = UploadgpthaikuForm() 15 if request.method == "GET": 16 return render_template("haiku/gptindex.html", form=form) 17 elif request.method == "POST" and form.validate: # htmlからの入力 18 session["posthaiku"] = form.haiku.data # htmlからの入力 19 print(session["posthaiku"]) 20 posthaiku = str(session["posthaiku"]) 21 filename = mubert(posthaiku) #作曲させた上で、その際のファイル名を取得 22 return render_template("haiku/gptindex.html", name=filename, form=form) 23 24 if __name__ == "__main__": 25 ha.debug = True 26 ha.run(host="0.0.0.0", port=int("5000"), debug=True) 27 28@ha.errorhandler(CSRFError) 29def handle_csrf_error(e): 30 return render_template("haiku/csrf_error.html", reason=e.description), 400

gptindex.html

1{% extends "haiku/base.html" %} 2{% block content %} 3<div class="alert alert-primary">GPT-3で俳句のBGMを作成してみませんか?</div> 4{% from "haiku/formhelper.html" import render_field %} 5 6<body> 7 <form action="/mubert" method="POST"> 8 {{ form.csrf_token }} 9 {{render_field(form.haiku)}} 10 {{form.submit()}} 11 </form> 12 <audio controls src="../{{name}}.mp3" controls></audio> 13</body> 14{%endblock %}

python

1mubert.py 2 3import datetime 4import json 5import time 6 7import httpx 8import numpy as np 9import requests 10from sentence_transformers import SentenceTransformer 11 12# haiku = str("winnie the pooh cooking methamphetamine") 13 14 15def mubert(haiku): 16 EMAIL_ADDRESS = "formail7300@gmail.com" 17 print(haiku) 18 PROMPT = f"{haiku}" 19 20 minilm = SentenceTransformer("all-MiniLM-L6-v2") 21 22 mubert_tags_string = "tribal,action,kids,neo-classic,run 130,pumped,jazz / funk,ethnic,dubtechno,reggae,acid jazz,liquidfunk,funk,witch house,tech house,underground,artists,mystical,disco,sensorium,r&b,agender,psychedelic trance / psytrance,peaceful,run 140,piano,run 160,setting,meditation,christmas,ambient,horror,cinematic,electro house,idm,bass,minimal,underscore,drums,glitchy,beautiful,technology,tribal house,country pop,jazz & funk,documentary,space,classical,valentines,chillstep,experimental,trap,new jack swing,drama,post-rock,tense,corporate,neutral,happy,analog,funky,spiritual,sberzvuk special,chill hop,dramatic,catchy,holidays,fitness 90,optimistic,orchestra,acid techno,energizing,romantic,minimal house,breaks,hyper pop,warm up,dreamy,dark,urban,microfunk,dub,nu disco,vogue,keys,hardcore,aggressive,indie,electro funk,beauty,relaxing,trance,pop,hiphop,soft,acoustic,chillrave / ethno-house,deep techno,angry,dance,fun,dubstep,tropical,latin pop,heroic,world music,inspirational,uplifting,atmosphere,art,epic,advertising,chillout,scary,spooky,slow ballad,saxophone,summer,erotic,jazzy,energy 100,kara mar,xmas,atmospheric,indie pop,hip-hop,yoga,reggaeton,lounge,travel,running,folk,chillrave & ethno-house,detective,darkambient,chill,fantasy,minimal techno,special,night,tropical house,downtempo,lullaby,meditative,upbeat,glitch hop,fitness,neurofunk,sexual,indie rock,future pop,jazz,cyberpunk,melancholic,happy hardcore,family / kids,synths,electric guitar,comedy,psychedelic trance & psytrance,edm,psychedelic rock,calm,zen,bells,podcast,melodic house,ethnic percussion,nature,heavy,bassline,indie dance,techno,drumnbass,synth pop,vaporwave,sad,8-bit,chillgressive,deep,orchestral,futuristic,hardtechno,nostalgic,big room,sci-fi,tutorial,joyful,pads,minimal 170,drill,ethnic 108,amusing,sleepy ambient,psychill,italo disco,lofi,house,acoustic guitar,bassline house,rock,k-pop,synthwave,deep house,electronica,gabber,nightlife,sport & fitness,road trip,celebration,electro,disco house,electronic" 23 mubert_tags = np.array(mubert_tags_string.split(",")) 24 mubert_tags_embeddings = minilm.encode(mubert_tags) 25 26 def get_track_by_tags(tags, pat, duration, maxit=20, autoplay=False, loop=False): 27 if loop: 28 mode = "loop" 29 else: 30 mode = "track" 31 r = httpx.post( 32 "https://api-b2b.mubert.com/v2/RecordTrackTTM", 33 json={ 34 "method": "RecordTrackTTM", 35 "params": { 36 "pat": pat, 37 "duration": duration, 38 "tags": tags, 39 "mode": mode, 40 }, 41 }, 42 ) 43 44 rdata = json.loads(r.text) 45 assert rdata["status"] == 1, rdata["error"]["text"] 46 trackurl = rdata["data"]["tasks"][0]["download_link"] 47 48 print("Generating track ", end="") 49 for i in range(maxit): 50 r = httpx.get(trackurl) 51 if r.status_code == 200: 52 # display(Audio(trackurl, autoplay=autoplay)) 53 save_file(trackurl) 54 break 55 time.sleep(1) 56 print(".", end="") 57 58 def find_similar(em, embeddings, method="cosine"): 59 scores = [] 60 for ref in embeddings: 61 if method == "cosine": 62 scores.append( 63 1 - np.dot(ref, em) / (np.linalg.norm(ref) * np.linalg.norm(em)) 64 ) 65 if method == "norm": 66 scores.append(np.linalg.norm(ref - em)) 67 return np.array(scores), np.argsort(scores) 68 69 def get_tags_for_prompts(prompts, top_n=3, debug=False): 70 prompts_embeddings = minilm.encode(prompts) 71 ret = [] 72 for i, pe in enumerate(prompts_embeddings): 73 scores, idxs = find_similar(pe, mubert_tags_embeddings) 74 top_tags = mubert_tags[idxs[:top_n]] 75 top_prob = 1 - scores[idxs[:top_n]] 76 if debug: 77 print( 78 f"Prompt: {prompts[i]}\nTags: {', '.join(top_tags)}\nScores: {top_prob}\n\n\n" 79 ) 80 ret.append((prompts[i], list(top_tags))) 81 return ret 82 83 # @markdown **Get personal access token in Mubert and define API methods** 84 email = EMAIL_ADDRESS # @param {type:"string"} 85 86 r = httpx.post( 87 "https://api-b2b.mubert.com/v2/GetServiceAccess", 88 json={ 89 "method": "GetServiceAccess", 90 "params": { 91 "email": email, 92 "license": "ttmmubertlicense#f0acYBenRcfeFpNT4wpYGaTQIyDI4mJGv5MfIhBFz97NXDwDNFHmMRsBSzmGsJwbTpP1A6i07AXcIeAHo5", 93 "token": "4951f6428e83172a4f39de05d5b3ab10d58560b8", 94 "mode": "loop", 95 }, 96 }, 97 ) 98 99 rdata = json.loads(r.text) 100 assert rdata["status"] == 1, "probably incorrect e-mail" 101 pat = rdata["data"]["pat"] 102 print(f"Got token: {pat}") 103 104 # @title **Generate some music 🎵** 105 106 prompt = PROMPT # @param {type:"string"} 107 duration = 30 # @param {type:"number"} 108 loop = False # @param {type:"boolean"} 109 110 def generate_track_by_prompt(prompt, duration, loop=False): 111 _, tags = get_tags_for_prompts( 112 [ 113 prompt, 114 ] 115 )[0] 116 try: 117 get_track_by_tags(tags, pat, duration, autoplay=True, loop=loop) 118 except Exception as e: 119 print(str(e)) 120 print("\n") 121 122 def save_file(url): 123 file_name = get_file_name() + ".mp3" 124 url_data = requests.get(url).content 125 126 with open(file_name, mode="wb") as f: 127 f.write(url_data) 128 129 def get_file_name(): 130 t_delta = datetime.timedelta(hours=9) 131 JST = datetime.timezone(t_delta, "JST") 132 now = datetime.datetime.now(JST) 133 global filename 134 d = now.strftime("%Y%m%d%H%M%S") 135 filename = d 136 return d 137 138 generate_track_by_prompt(prompt, duration, loop) #楽曲生成  139 140 print(filename) 141 142 return filename

python

1formgpt.py 2 3from flask_wtf.form import FlaskForm 4from wtforms import TextAreaField 5from wtforms.fields.simple import SubmitField 6from wtforms.validators import Length 7 8 9class UploadgpthaikuForm(FlaskForm): 10 haiku = TextAreaField( 11 "俳句を入力してください:", validators=[Length(min=8, max=60, message="俳句の長さにしてください")] 12 ) #winnie the pooh cooking methamphetamine のように入力します 13 submit = SubmitField("アップロード")

試したこと

https://self-development.info/%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%8B%E3%82%89%E9%9F%B3%E6%A5%BD%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8Bmubert-text-to-music%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/

こちらの記事を参考に、自動作曲アプリを作っています。

chatGPTに簡易的な質問を繰り返しても特にわからなかった

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dameo

2022/12/07 05:37

chromeならローカルファイルを<a href="..../xxx.mp3">play</a>とかで作って開くだけでもリンククリックで再生はできますけど… 知りたい内容だけをピンポイントに絞って最小限のコードにしてから質問しましょう。
moukin

2022/12/07 06:41

<audio controls src="../{{ name }}.mp3" controls></audio>の部分を、<a href ="....>のおっしゃっていただいたリンクを作成しても、http://127.0.0.1:5000/..../20221207144259.mp3が開かれ、404のNot foundが生じました。 ピンポイントに絞るべきところがわからずに申し訳ございません。 flaskでは、render_templateした場合でも、ローカルファイルを読み込んでいると思うのですが、 コンソールでのログが、 "GET /flaskbook/20221207150647.mp3 HTTP/1.1" 404 -と、 GETの中のパスでは再生したいファイルまで通せているのに、404と見つかっていない状況を直したいというのが現状の質問だと考えます。
dameo

2022/12/07 06:47

それはflaskにアクセスした場合ですよね? エクスプローラーから開いたわけではないですよね?
guest

回答1

0

ベストアンサー

音楽再生はしたことがありませんが、以下の部分の"../"というのは、ブラウザからアクセスするパスです。

html

1<audio controls src="../{{name}}.mp3" controls></audio>

http://localhost:5000/でアクセスしているページであればhttp://localhost:5000/../ですので、そのパスでファイルを公開しているかという話になると思います。
Flaskの場合デフォルトで公開されているのはstaticフォルダだけなので、そんなパスは無いはずです。
FlaskからBlueprintを使って別のパス(例えば/audio/{filename}とか)を公開し、それのパスをurl_forなどを使って指定したり、nginxなどを使って、該当フォルダを公開してそちらを指定したりすればブラウザからアクセスできるようになるんじゃないでしょうか。

ついでですが、..が指定可能なのはディレクトリトラバーサルが可能になってしまうとうことなので、使えないようにした方が良いと思います。

投稿2022/12/07 06:34

FiroProchainezo

総合スコア2387

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moukin

2022/12/07 06:52

staticにローカルファイルで参照するべきファイルを置くのが基本というアドバイスを参考にもらいまして、 model_dir = rf"C:/Users/.../flaskbook/{filename}.mp3" new_path = shutil.move(model_dir, r"C:/Users/81804/flaskbook/apps/static/") で対象の楽曲ファイルを動かした後に、 <audio controls src="../../../static/{{ name }}.mp3" controls></audio>で読み込ませることで、 音楽を再生することができました!! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問