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

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

新規登録して質問してみよう
ただいま回答率
86.12%
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ライブラリです。

解決済

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

senseIY
senseIY

総合スコア277

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ライブラリです。

1回答

0リアクション

0クリップ

354閲覧

投稿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

export function WSF() { const waveformRef = useRef(null); var context = null; console.log(waveformRef) const handlePlayPause = () => { waveformRef.current.playPause(); console.log("handlePlayPause") } const handleChangeFile = (e) => { if (context == null) { window.AudioContext = window.AudioContext || window.webkitAudioContext; context = new AudioContext(); waveformRef.current = WaveSurfer.create({ container: waveformRef.current, audioContext: context, }); console.log(waveformRef); } const file = e.target.files[0] console.log(file) if (file) { const fileUrl = URL.createObjectURL(file) waveformRef.current.load(fileUrl); console.log(fileUrl) } } return ( <div> <div ref={waveformRef}></div> <input type="file" accept="audio/*" onChange={(e) => handleChangeFile(e)} /> <button onClick={handlePlayPause}>Play/Pause</button> </div> ); }

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

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

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

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

js

// そのままパラメータを渡した場合。p_fileが取得した音声ファイルのパラメータ export function WSF_stock(p_file) { const waveformRef = useRef(null); var context = null; const handlePlayPause = () => { waveformRef.current.playPause(); console.log("handlePlayPause") } const handleChangeFile = (e) => { if (context == null) { // context = new AudioContext(); window.AudioContext = window.AudioContext || window.webkitAudioContext; context = new AudioContext(); waveformRef.current = WaveSurfer.create({ container: waveformRef.current, audioContext: context, }); // ここから console.log(waveformRef) console.log(p_file) waveformRef.current.load(p_file); // ここまでを入れ替えていきます } } return ( <div> <div ref={waveformRef}></div> <button onClick={(e) => handleChangeFile(e)}>ロード</button> <button onClick={handlePlayPause}>Play/Pause</button> </div> ); } // console {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/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--b196a9a15bdc6cd3711c34dd46ca1a27962720a3/%E3%83%AF%E3%82%B9%E3%83%AC%E3%83%8A%E3%82%B0%E3%82%B5.mp3" [[Prototype]]: Object このようにデータは渡っている

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

js

const new_file = new File([p_file], "保存された音声",{type: "audio/mpeg"}) const NewFile = URL.createObjectURL(new_file) waveformRef.current.load(NewFile); // console {current: WaveSurfer}current: WaveSurfer {_disabledEventEmissions: Array(0), handlers: null, defaultParams: {}, backends: {}, util: {}, …}[[Prototype]]: Object wavesurfer.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-- ad9777f976b16c2879d73e76e7d749f1ba2c1293/%E3%83%AF%E3%82%B9%E3%83%AC%E3%83%8A%E3%82%B0%E3%82%B5.mp3"[[Prototype]]: Object wavesurfer.jsx:85

blobにして渡してみる

js

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

ファイルにしてみる

js

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

ロードの仕方を変える

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

自分の考察

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

js

File {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 wavesurfer.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

以下のような質問にはリアクションをつけましょう

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

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

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

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

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

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

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ライブラリです。