Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: refactor HTMLAudioPlayer #316

Merged
merged 3 commits into from
Jul 18, 2024

Conversation

yu-ogi
Copy link
Contributor

@yu-ogi yu-ogi commented Jul 10, 2024

このPullRequestが解決する内容

HTMLAudioPlayer をリファクタリングします。

  • HTMLAudioPlayerHTMLAudioElement の間に HTMLAudioPlayerContext を追加します。

仕様

  • duration が未定義の場合は全体を再生します
  • offset が未定義の場合は最初から再生します
  • loopOffset が未定義の場合はループ時に最初から再生します

asset: HTMLAudioAsset;
}

export class HTMLAudioPlayerContext {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTMLAudioElement を直接操作する抽象化的なクラスを新規で作成します。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

切り出す方針同意なのですが、名前づけが難しいですね。

  • AudioPlayer と g.AudiPlayContext
  • HTMLAudioPlayer と HTMLAudioPlayerContext

で "player" と "context" の関係が逆になっているように思います (前者は context が player で実装されている一方、後者は context で player が実装されている) 。 "play context" と "player context" で別の語だと解釈することもできそうですが、名前からはあまり違いが読み取れなさそうです。

コメントされているとおり主眼は HTMLAudioElement の制御にあると思いますから、いっそのこと PDI 切り離して、純粋に 「HTMLAudioElement を制御する役」にしてしまうのはどうでしょうか? HTMLAudioElement (cloneElement() された) と、duration や offset を生成時の引数として受け取る形にすれば、PDI 依存もなくなると思います。("たまたま" asset と同じ形の interface で duration, offset, loopOffset などを受け取ることもできると思います)

この時、名前は AudioElement を軸に命名できそうです。それでも名付けにくいですが、例えば LoopableAudioElement とか、 AudioElementController とかですかね。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

おっしゃるとおり 「HTMLAudioElement を制御するプレイヤー実装」という切り出し方にした方がシンプルになりそうなので、88025ed にて修正しました。

名前については変に長くなっても分かりづらいだけな気がしたため AudioElementPlayer としました。

this._previousCurrentTime = element.currentTime * 1000;

if (this.offsetEnd < currentOffset + deltaSinceLastCall || this.offsetEnd <= currentOffset) {
this._setRewindTimer(deltaUntilEnd);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTMLAudioPlayer が複雑になっている要因は「複数箇所で同じような処理をしている」「それらの内どちらかの処理が終わっていればもう一方の処理を中断する」というような状態管理によるものだと仮定しました。

その仮定のもと

  • 音声の再生・停止・巻き戻しを機能単位で切り分け
    • HTMLAudioPlayer はそれらの機能を呼ぶだけ
  • 音声が終端に達したときの処理 (非ループの場合は停止、ループの場合は先頭に戻るなど) を一元化

するように修正しました。

@yu-ogi yu-ogi requested review from kamakiri01 and xnv July 10, 2024 08:34

setupChromeMEIWorkaround(audio);
audio.volume = this._calculateVolume();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この箇所に対応する、 play() 時の HTMLAudioElement#volume の設定箇所が消えたように見えますが、外部影響ないでしょうか?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

見落としてました。5c4045f にて修正済みです。

asset: HTMLAudioAsset;
}

export class HTMLAudioPlayerContext {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

切り出す方針同意なのですが、名前づけが難しいですね。

  • AudioPlayer と g.AudiPlayContext
  • HTMLAudioPlayer と HTMLAudioPlayerContext

で "player" と "context" の関係が逆になっているように思います (前者は context が player で実装されている一方、後者は context で player が実装されている) 。 "play context" と "player context" で別の語だと解釈することもできそうですが、名前からはあまり違いが読み取れなさそうです。

コメントされているとおり主眼は HTMLAudioElement の制御にあると思いますから、いっそのこと PDI 切り離して、純粋に 「HTMLAudioElement を制御する役」にしてしまうのはどうでしょうか? HTMLAudioElement (cloneElement() された) と、duration や offset を生成時の引数として受け取る形にすれば、PDI 依存もなくなると思います。("たまたま" asset と同じ形の interface で duration, offset, loopOffset などを受け取ることもできると思います)

この時、名前は AudioElement を軸に命名できそうです。それでも名付けにくいですが、例えば LoopableAudioElement とか、 AudioElementController とかですかね。

Copy link
Member

@xnv xnv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメント加えていますが approved.

export interface HTMLAudioPlayerContextParameterObject {
asset: HTMLAudioAsset;
export interface AudioElementPlayerParameterObject {
id: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id 使ってなさそうですし定義的にもアセットのIDであって HTMLAudioElement の再生には関係なさそうなので削りませんか。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (asset.id === this._player.id) {

かなり歪な存在ではありますが、同一アセットの判定に使っているので一旦このままとさせてください。

@yu-ogi yu-ogi merged commit ae750cc into feat-loopoffset Jul 18, 2024
8 checks passed
@yu-ogi yu-ogi deleted the refactor-html-audio-player branch July 18, 2024 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants