HarmonyOS 運動アプリ開発実践:独自の運動ビデオプレーヤーの作成
HarmonyOS 核心技術##運動開発##Media Kit(メディアサービス)
現在のデジタル時代において、運動フィットネスは多くの人々の生活の一部となっています。本日はアプリにビデオプレーヤーを追加し、ユーザーが運動前にウォーミングアップし、運動後にストレッチングを行うことを支援します。この記事ではコードの核心部分に焦点を当て、開発プロセスにおける重要な技術と実装の詳細をステップバイステップで理解するお手伝いをします。

- プロジェクトの背景とニーズ分析
アプリを開発する前に、ニーズを明確にすることは非常に重要です。運動ビデオプレーヤーの場合、以下のコア機能を考慮する必要があります:
-
ビデオ再生:ウォーミングアップやストレッチングなど、運動関連のビデオを再生する機能をサポートします。
-
ユーザーインタラクション:再生、一時停止、再開などの基本的なボタン操作を提供します。
-
コードの核心部分の整理と解析
次に、コードの核心部分をたどりながら、運動ビデオプレーヤーの実装における重要なステップを段階的に解析していきます。
(1)ページレイアウトとナビゲーション
HarmonyOS開発において、ページレイアウトはユーザー体験の基本です。LibNav
とLibPage
を使用して、ページのナビゲーションとコンテンツレイアウトを構築しました。以下がコードの核心部分です:
@Component
export struct SportHelperPage {
@Builder
pageNavBuilder(){
LibNav({
pageTitle: "運動アシスタント"
}).width("100%")
}
@Builder
pageContentBuilder(){
Column() {
Text('運動アシスタント')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ top: 20 })
Button('ランニング前のウォーミングアップ')
.onClick(() => this.playVideo('<url id="d1gafmccoua8uhit6r70" type="url" status="failed" title="" wc="0">https://video.111.com/p/bms/warmup_before_running.mp4</url> '))
.margin({ top: 10 })
Button('ランニング後のストレッチ')
.onClick(() => this.playVideo('<url id="d1gafmccoua8uhit6r7g" type="url" status="failed" title="" wc="0">https://video.111.com/p/bms/stretch_after_running.mp4</url> '))
.margin({ top: 10 })
Button('再生一時停止')
.onClick(() => {
this.avPlayer?.pause()
})
Button('再生再開')
.onClick(() => {
this.avPlayer?.play()
})
XComponent({ type: XComponentType.SURFACE, controller: mXComponentController })
.width('100%')
.height(300)
}
.padding(20)
.backgroundColor(Color.White)
}
}
- ページナビゲーション:
LibNav
を使用して、ページタイトルを「運動アシスタント」に設定し、幅を100%に設定してナビゲーションバーが画面の上部全体を覆うようにします。 - ページコンテンツ:
Column
レイアウトを使用して、テキスト、ボタン、ビデオプレーヤーコンポーネント(XComponent
)を順に配置します。各ボタンにはクリックイベントがバインドされており、ビデオの再生や再生状態の制御をトリガーします。
(2)ビデオプレーヤーの初期化と制御
ビデオ再生はアプリのコア機能であり、HarmonyOSのmedia.AVPlayer
を使用して実装しました。以下が初期化と再生制御のコードです:
async initPlay() {
try {
this.avPlayer = await media.createAVPlayer();
this.setAVPlayerCallback(this.avPlayer);
} catch (error) {
console.error('ビデオの初期化に失敗しました:', error);
}
}
async playVideo(url: string) {
try {
if(this.avPlayer){
this.avPlayer.url = url;
this.avPlayer.play();
}
} catch (error) {
console.error('ビデオの再生に失敗しました:', error);
}
}
- プレーヤーの初期化:
media.createAVPlayer()
を使用してAVPlayer
インスタンスを生成し、コールバック関数を登録して再生状態の変化を監視します。 - ビデオの再生:
avPlayer.url
プロパティにビデオのURLを設定し、play()
メソッドを呼び出して再生を開始します。ただし、ビデオURLが有効でなければ再生に失敗するため、注意が必要です。
(3)ステートマシンコールバックとエラーハンドリング
ビデオ再生中に、さまざまな状態の変化やエラーが発生する可能性があります。コールバック関数を登録することで、これらの状況をより効果的に管理できます:
setAVPlayerCallback(avPlayer: media.AVPlayer) {
avPlayer.on('startRenderFrame', () => {
console.info(`AVPlayer start render frame`);
});
avPlayer.on('seekDone', (seekDoneTime: number) => {
console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
});
avPlayer.on('error', (err: BusinessError) => {
console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
avPlayer.reset();
});
avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
switch (state) {
case 'idle':
avPlayer.release();
break;
case 'initialized':
const id = mXComponentController.getXComponentSurfaceId();
avPlayer.surfaceId = id;
avPlayer.prepare();
break;
case 'prepared':
avPlayer.play();
break;
case 'paused':
console.info('AVPlayer state paused called.');
break;
case 'completed':
avPlayer.stop();
break;
case 'stopped':
avPlayer.reset();
break;
case 'released':
console.info('AVPlayer state released called.');
break;
default:
console.info('AVPlayer state unknown called.');
break;
}
});
}
-
ステートコールバック:
stateChange
イベントを監視することで、異なるステート(initialized
、prepared
、playing
など)に応じて適切な操作を実行します。たとえば、initialized
ステートでは、再生画面のsurfaceId
を設定し、prepare()
メソッドを呼び出して再生を準備します。 -
エラーハンドリング:
error
イベントを監視して、再生中に発生する可能性のあるエラーをキャッチし、reset()
メソッドを呼び出してプレーヤーのステートをリセットします。 -
開発における注意点と最適化の提案
開発プロセス中には、アプリの安定性とユーザー体験を確保するために、以下の重要なポイントに注意する必要があります:
-
ビデオURLの有効性:
playVideo()
メソッドを呼び出す際には、渡されたURLが有効であることを確認する必要があります。URLが無効またはネットワークが使用できない場合、プレーヤーは正常に動作しません。実際の開発では、ビデオURLを検証し、友好的なエラーメッセージを提供することをお勧めします。 -
パフォーマンスの最適化:ビデオのロード時間を短縮するためには、アプリの起動時にビデオリソースを事前に読み込むことを検討することができます。さらに、システムリソースを不要な時に占有しないように、プレーヤーのライフサイクルを適切に管理することも重要です。
-
ユーザー体験:ページレイアウトにおいて、ボタンやテキストの配置は简洁で明瞭でなければなりません。複雑な操作を避けるべきです。また、プログレスバー、音量コントロール機能などの追加を検討することで、ユーザー体験をさらに向上させることができます。
-
まとめ
実際の開発において、開発者はニーズに応じて機能をさらに拡張することができます。例えば、より多くの運動ビデオカテゴリーを追加したり、オフラインダウンロードをサポートするなどです。
Discussion