💨

HarmonyOS開発実践:動的音声コントロールマイクの開発ガイド

に公開

まえがき

HarmonyOSのエコシステムにおいて、開発者は常にユーザーに豊富なインタラクティブなエクスペリエンスを提供するための探求と革新を続けています。最近、私はマイクコンポーネントを制作するアイデアを思いつきました。このマイクは音声に応じて動的に変化します。ネットワーク上には既成のリファレンスケースがほとんどないため、私はこのアイデアを現実のものにするために自分で手を動かすことにしました。本稿では、この開発プロセスを深く解析し、実践経験と技術的な詳細を共有します。

一、事前準備

開始する前に、マイクの動的効果のベースとなる2枚の画像を準備する必要があります。これらの画像をプロジェクトのentry/etsディレクトリに配置し、コードで適切な設定を行います。

画像の説明

画像の説明

最終的な効果:

画像のアップロード中

コードの例:

private img: ImageBitmap = new ImageBitmap("image/img.png");
private img2: ImageBitmap = new ImageBitmap("image/img_1.png");

二、描画に必要なクラスの理解

動的効果を実現するためには、いくつかの重要なクラスとオブジェクトを理解し、使用する必要があります。これらのクラスは、Canvas上で描画と効果処理を行うのに役立ちます。

RenderingContextSettingsCanvasRenderingContext2Dオブジェクトを設定するためのもので、アンチエイリアス機能のオン/オフを含みます。

private settings: RenderingContextSettings = new RenderingContextSettings(true);

CanvasRenderingContext2D:描画コンテキストを作成するために使用され、Canvas内にグラフィックを描画することができます。

private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);

OffscreenCanvas:オフスクリーンキャンバスは、メインスレッドに影響を与えることなく描画操作を行うことができます。

private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 600);

三、マイクの表示効果ルールを定義する

マイクの動的効果は、音声の強度に応じて変化します。0から5までの5つのレベルを定義し、それぞれが異なる音声強度を表します。この効果をシミュレートするために、ランダムな音声レベルを生成する関数を書きました。

ランダムな音声レベルを生成する関数:

generateRandomNumberUpToFive(): number {
  const randomInt = Math.floor(Math.random() * 5); // 0, 1, 2, 3, 4
  // 1/5の確率で5を返す
  if (Math.random() < 0.2) {
    return 5;
  }
  return randomInt;
}

動的効果を実現するために、一定の間隔で音声レベルを更新するタイマーを使用し、コンポーネントが初期化されたときにこのプロセスを開始します。

コンポーネントの初期化:

@State @Watch('draw') level: number = 3;

aboutToAppear(): void {
  setInterval(() => {
    this.level = this.generateRandomNumberUpToFive();
  }, 300);
}

四、キーコード

動的効果を実現する際には、まず以前の描画効果を消去し、その後音声レベルに応じてマイクの動的レイヤー効果を描画します。最後に、これらの効果を重ね合わせることで、最終的な動的効果を表示します。

描画のロジック:

draw() {
  this.context.clearRect(0, 0, 192, 192);
  let offContext = this.offCanvas.getContext("2d", this.settings);
  offContext.drawImage(this.img2, 0, 0, 192, 192);
  let h = this.level * 192 / 5;
  let imagedata = offContext.getImageData(0, h, 192, 192);
  offContext.drawImage(this.img, 0, 0, 192, 192);
  offContext.putImageData(imagedata, 0, h);
  let image = this.offCanvas.transferToImageBitmap();
  this.context.transferFromImageBitmap(image);
}

五、全体のコード効果

上記のコードを1つのコンポーネントに統合し、コンポーネントが初期化されたときに背景を描画し、必要に応じて動的効果を更新します。

完整的组件代码:

@Component
struct CanvasExample1 {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 600);
  private img: ImageBitmap = new ImageBitmap("image/img.png");
  private img2: ImageBitmap = new ImageBitmap("image/img_1.png");

  @State @Watch('draw') level: number = 3;

  draw() {
    this.context.clearRect(0, 0, 192, 192);
    let offContext = this.offCanvas.getContext("2d", this.settings);
    offContext.drawImage(this.img2, 0, 0, 192, 192);
    let h = this.level * 192 / 5;
    let imagedata = offContext.getImageData(0, h, 192, 192);
    offContext.drawImage(this.img, 0, 0, 192, 192);
    offContext.putImageData(imagedata, 0, h);
    let image = this.offCanvas.transferToImageBitmap();
    this.context.transferFromImageBitmap(image);
  }

  generateRandomNumberUpToFive(): number {
    const randomInt = Math.floor(Math.random() * 5); // 0, 1, 2, 3, 4
    if (Math.random() < 0.2) {
      return 5;
    }
    return randomInt;
  }

  aboutToAppear(): void {
    setInterval(() => {
      this.level = this.generateRandomNumberUpToFive();
    }, 300);
  }

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .onReady(() => {
          let offContext = this.offCanvas.getContext("2d", this.settings);
          offContext.drawImage(this.img, 0, 0, 192, 192);
        });
    }
    .width('100%')
    .height('100%');
  }
}

六、おわりに

本稿では、動的音声コントロールマイクコンポーネントを実現するだけでなく、HarmonyOSにおける描画APIと動的効果の実現方法について詳しく解説しました。この記事が他の開発者にインスピレーションとガイダンスを提供し、HarmonyOSエコシステムの革新と発展に寄与することを願っています。

Discussion