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

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

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

810閲覧

rails側に保存した音声ファイルをReact側のwavesurferで使用したい。

senseIY

総合スコア281

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2022/08/07 04:27

編集2022/08/07 05:25

解決したいこと

rails側に保存した音声ファイルをReact側のwavesurferで使用したいです。

環境

・dockerを使用して、バックエンド側(RoR)とフロントエンド側{React TypeScript *(wavesurferなどの一部はJavaScript)}に分けて開発を行っています。OSはWindowsですが、wsl2のUbuntu20.04で開発を行っています。
・Rails側では、CarrierwaveとActive_storageを試してみましたが、どちらもrails側に保存した音声ファイルをReact側のwavesurferで使用した時のみ上手くWevesurferで描画できませんでした。現在はActive_storageを使用しています。

発生している問題

エラーは発生しないのですが、rails側に保存した音声ファイルをReact側のwavesurferで使用した時にのみWevesurferの波形が描写されません。

1 その場でアップロードしたファイルをwevesurferで使う場合

こちらのサイトを参考にさせて頂き、そのまま使用しています。

https://www.wizard-notes.com/entry/javascript/react-wavesurfer-js

js

1export function WSF() { 2 3const waveformRef = useRef(null); 4 var context = null; 5 console.log(waveformRef) 6 7 const handlePlayPause = () => { 8 waveformRef.current.playPause(); 9 console.log("handlePlayPause") 10 } 11 12 const handleChangeFile = (e) => { 13 if (context == null) { 14 window.AudioContext = window.AudioContext || window.webkitAudioContext; 15 context = new AudioContext(); 16 17 waveformRef.current = WaveSurfer.create({ 18 container: waveformRef.current, 19 audioContext: context, 20 }); 21 console.log(waveformRef); 22 } 23 24 const file = e.target.files[0] 25 console.log(file) 26 if (file) { 27 const fileUrl = URL.createObjectURL(file) 28 waveformRef.current.load(fileUrl); 29 console.log(fileUrl) 30 } 31 } 32 33 return ( 34 <div> 35 <div ref={waveformRef}></div> 36 <input type="file" accept="audio/*" onChange={(e) => handleChangeFile(e)} /> 37 <button onClick={handlePlayPause}>Play/Pause</button> 38 </div> 39 ); 40}

この場合、ファイルを選択すると、wevesurferで正常に波形が描写されます。

1` このコードを参考にしてローカル(Rails側)のファイルを使用できるか?

以下のコードを全て試してみましたが、どれもエラーは出ないものの、波形が描写されませんでした。また、useRefを使用する都合上、ロードボタンをクリックしてから波形が描写されるという仕様になっています。また、同じ部分は省略しました。

そのままパラメータを渡した場合

js

1// そのままパラメータを渡した場合。p_fileが取得した音声ファイルのパラメータ 2export function WSF_stock(p_file) { 3 const waveformRef = useRef(null); 4 var context = null; 5 6 const handlePlayPause = () => { 7 waveformRef.current.playPause(); 8 console.log("handlePlayPause") 9 } 10 11 const handleChangeFile = (e) => { 12 13 if (context == null) { 14 // context = new AudioContext(); 15 window.AudioContext = window.AudioContext || window.webkitAudioContext; 16 context = new AudioContext(); 17 18 waveformRef.current = WaveSurfer.create({ 19 container: waveformRef.current, 20 audioContext: context, 21 }); 22// ここから 23 console.log(waveformRef) 24 console.log(p_file) 25 waveformRef.current.load(p_file); 26// ここまでを入れ替えていきます 27 28 } 29 } 30 return ( 31 <div> 32 <div ref={waveformRef}></div> 33 <button onClick={(e) => handleChangeFile(e)}>ロード</button> 34 <button onClick={handlePlayPause}>Play/Pause</button> 35 </div> 36 ); 37 } 38 39// console 40{file: '/rails/active_storage/blobs/redirect/eyJfcmFpbHMiO…%E3%82%B9%E3%83%AC%E3%83%8A%E3%82%B0%E3%82%B5.mp3'} 41file: "/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--b196a9a15bdc6cd3711c34dd46ca1a27962720a3/%E3%83%AF%E3%82%B9%E3%83%AC%E3%83%8A%E3%82%B0%E3%82%B5.mp3" 42[[Prototype]]: Object 43このようにデータは渡っている 44

一旦ファイルオブジェクトを生成してからそれをURLにしてロード

js

1const new_file = new File([p_file], "保存された音声",{type: "audio/mpeg"}) 2const NewFile = URL.createObjectURL(new_file) 3waveformRef.current.load(NewFile); 4 5// console 6 7{current: WaveSurfer}current: WaveSurfer {_disabledEventEmissions: Array(0), handlers: null, defaultParams: {}, backends: {}, util: {}, …}[[Prototype]]: Object 8wavesurfer.jsx:69 {file: '/rails/active_storage/blobs/redirect/eyJfcmFpbHMiO…%E3%82%B9%E3%83%AC%E3%83%8A%E3%82%B0%E3%82%B5.mp3'}file: "/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19-- 9ad9777f976b16c2879d73e76e7d749f1ba2c1293/%E3%83%AF%E3%82%B9%E3%83%AC%E3%83%8A%E3%82%B0%E3%82%B5.mp3"[[Prototype]]: Object 10wavesurfer.jsx:85

blobにして渡してみる

js

1const blob = new Blob([p_file], {type: "audio/mpeg"}) 2const NewFile = URL.createObjectURL(blob) 3console.log(NewFile) 4waveformRef.current.load(NewFile);

ファイルにしてみる

js

1const Newfile = new File([p_file], "保存された音声",{type: "audio/mpeg"}) 2waveformRef.current.load(NewFile);

ロードの仕方を変える

waveformRef.current.load(); => waveformRef.current.loadBlob();

自分の考察

・このコードの場合、ファイルをそのまま直接アップロードした場合にしかwevesurferの描写を受け付けないという結論に至りました。ファイルを直接渡すと、

js

1File {name: 'Night_Sea.mp3', lastModified: 1647685053601, lastModifiedDate: Sat Mar 19 2022 19:17:33 GMT+0900 (日本標準時), webkitRelativePath: '', size: 947012, …}lastModified: 1647685053601lastModifiedDate: Sat Mar 19 2022 19:17:33 GMT+0900 (日本標準時) {}name: "Night_Sea.mp3"size: 947012type: "audio/mpeg"webkitRelativePath: ""[[Prototype]]: File 2wavesurfer.jsx:35 blob:http://localhost:4000/8d6613ff-4084-4952-a218-6c97701ddb0c

 このように描写されます。一応これと同じように、一旦保存しているデータをファイルにして入れてみましたがなぜか上手く描写されませんでした。
また、ここで詰まってしまったため、新しい方法を模索していると、

https://www.npmjs.com/package/wavesurfer-react#wavesurfer

このWevesurferをReactで使えるようにするJSライブラリーを見つけたので、使用してみることにしました。

2 ローカル(フロントエンド側)に保存した音声ファイルを再生する場合

*このライブラリーは新しいため、参考記事が少なく、手探りで仕様を何とか把握しようとしたため、間違った認識をしているかもしれません

https://codesandbox.io/s/wavesurfer-react-20-gqvb6

・このライブラリーの仕様は恐らく、フロントエンド側のパブリックディレクトリにある音声ファイルのみにアクセス可能だと思われます。
・試しに別のディレクトリ(imgなど)を作成して音声ファイルを移動させてみたところ、相対パスが正しくても音声ファイルを読み込まないことを確認しました。
・私の作成しているアプリの挙動としては、
1 React側で音声ファイルなどのデータを受け取り、axiosでrails側にPostし保存。音声ファイルはActiveStrageに保存される。
2 Getリクエストを送ってrails側からデータ取得
3 取得したデータを使用してwevesurferにデータを入れて波形を描写
という挙動をして欲しいため、このライブラリーの使用を断念致しました。

また、一応ActiveStrageを使用する際に参考にしたサイトを載せておきます

https://dev.to/jblengino510/uploading-files-in-a-react-rails-app-using-active-storage-201c

その他

・一応rails側に保存した音声ファイルをReact側のwavesurferで使用する時にのみ、波形が描写されないだけで、データの受け渡しは出来ていると思われます。他にnameやanswerなどのカラムが存在しますが、上手く値を取得できていました。
・フロントエンド側とバックエンド側に分割しないで使用した際(これと別のアプリ)は上手く描写できていました。
・問題解決のために必要な重要な情報(ファイルなど)が抜けているかもしれません。その際はご指摘いただけますと幸いです。
・何かしらアドバイスがあればよろしくお願いいたします。

追記
マルチポストをしています。不快に思われたら申し訳ございません。
https://ja.stackoverflow.com/questions/90418/rails%e5%81%b4%e3%81%ab%e4%bf%9d%e5%ad%98%e3%81%97%e3%81%9f%e9%9f%b3%e5%a3%b0%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%92react%e5%81%b4%e3%81%aewavesurfer%e3%81%a7%e4%bd%bf%e7%94%a8%e3%81%97%e3%81%9f%e3%81%84

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

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

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

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

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

guest

回答1

0

自己解決

URLの指定の仕方が間違っていました。正しくは

js

1const corsAudio = new Audio(p_file.file.url); 2waveformRef.current.load(corsAudio);

このように、オブジェクトをそのまま渡すのではなく、データベースから取ってきたfileオブジェクトのurlプロパティを指定して値を渡す必要があります。

投稿2022/08/12 02:29

senseIY

総合スコア281

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問