Sassyブログ

埼玉県在住のシステムエンジニアです。多ジャンルなブログですが、基本的にはIT関連の内容を中心に他のちょいちょい他ジャンルの記事も発信していきます。

Safariで動画を開いた時に途中から再生できなかった時の対処法

f:id:y_saiki:20210917093615p:plain

問題

ページを開いたときに途中から再生を行う機能を実装したのですが、なぜかSafariでは途中再生がされず最初からの再生となってしまう事象が発生していました。

ChromeFireFox、Edgeでは等のブラウザではしっかり途中から再生されています。

ブレークポイントを張ってデバッグを行ったところvideoElement.currentTimeに値を設定しても値が更新されていない動きをしていました。

他のブラウザでは同様にデバッグすると値が更新されています。

簡単に実装を説明するとReactで開発をしているのでuseEffectを使ってマウントされた時にAPIから返ってきた再生位置を見てvideoElement.currentTimeに値を設定するという実装をしてました。

原因

Safariではメディア再生可能前にcurrentTimeを設定しても設定されない不具合があるようです。

以下はiOS SafariですがMac Safariでも同様でした。

stackoverflow.com

Safariではメディアが再生可能状態になってからでないとcurrentTimeがうまく機能しないようです。

対処方法

なのでcanPlayイベントを検知してメディア再生可能状態となってからcurrentTimeの更新を行うように修正しました。 以下の実装イメージです。(コードは適当)

const handleCanPlay = useCallback(()=>{
    ・・・省略
    videoElement.currentTime = 20;
    ・・・省略
}, [・・・省略])

こちらでMediaHTMLElementのイベントの挙動が確認できますのでオススメです。

listener.noplan.cc

上記で確認するとcanPlayは2回呼ばれているようで、そのままイベントハンドラに処理を書いていると2回呼ばれてしまい無駄に処理が行われてしまうのでuseStateを使って1度だけ実行されるように調整しました。

const [isUpdated, setIsUpdated] = useState(false);
const handleCanPlay = useCallback(()=>{
    if(isUpdated){
        return;
    }
    ・・・省略
    videoElement.currentTime = 20;
    ・・・省略
    setIsUpdated(true);
}, [・・・省略])