Mobile Development 12 min read

HarmonyOS Video Transcoding with AVTranscoder: Complete Start-Pause-Resume Flow

This tutorial demonstrates a full video transcoding workflow on HarmonyOS using the AVTranscoder API, covering instance creation, progress tracking, pause/resume/cancel controls, and playback of the transcoded output, with complete ArkTS code examples.

51CTO HarmonyOS Developer Community
51CTO HarmonyOS Developer Community
51CTO HarmonyOS Developer Community
HarmonyOS Video Transcoding with AVTranscoder: Complete Start-Pause-Resume Flow

Project Overview

The sample implements a complete video transcoding flow: start transcoding, pause, resume, and completion with playback. It uses HarmonyOS's AVTranscoder from the MediaKit to transcode a local MP4 file to MPEG-4 format at 1920x1080, 30 fps, 5 Mbps bitrate.

Project repository:

https://gitcode.com/HarmonyOS_Samples/UseAVTranscoderVideo

Function Overview

Video transcoding using AVTranscoder

Progress display during transcoding

Pause and resume transcoding

Cancel transcoding operation

Playback of transcoded video on completion

Technical Architecture

Project Structure

177-UseAVTranscoderVideo/├── entry/src/main/ets/│   ├── entryability/│   │   └── EntryAbility.ets          # App entry│   ├── pages/│   │   ├── index.ets                 # Home page│   │   ├── TranscoderFinishPage.ets  # Transcoding completion page│   │   └── VideoTranscoderPage.ets   # Transcoding progress page│   └── utils/│       └── AVTranscoderManager.ets   # Transcoding management class└── entry/src/main/resources/    └── rawfile/        └── video_sample.mp4          # Source video for transcoding

Core Technical Points

AVTranscoder : Video transcoding management class

createAVTranscoder : Create transcoding instance

startTranscode : Start transcoding

pause/resume : Pause/resume transcoding

Core Implementation

Creating the Transcoder Instance

The AVTranscoderManager class encapsulates the transcoding logic. It creates an AVTranscoder instance via media.createAVTranscoder() and registers three event listeners:

// entry/src/main/ets/utils/AVTranscoderManager.etsimport { media } from '@kit.MediaKit';export class AVTranscoderManager {  private transcoder?: media.AVTranscoder;  private outputPath: string = '';  // Create transcoder instance  async createTranscoder(): Promise<void> {    this.transcoder = await media.createAVTranscoder();    // Register progress update listener    this.transcoder.on('progressUpdate', (progress: number) => {      console.log('Transcoding progress:', progress);    });    // Register error listener    this.transcoder.on('error', (err: BusinessError) => {      console.error('Transcoding error:', JSON.stringify(err));    });    // Register completion listener    this.transcoder.on('complete', () => {      console.log('Transcoding complete');    });  }  // Start transcoding  async startTranscode(    inputPath: string,    outputPath: string  ): Promise<void> {    if (!this.transcoder) {      await this.createTranscoder();    }    this.outputPath = outputPath;    // Configure transcoding parameters    const outputFormat: media.OutputFormat = {      fileFormat: media.ContainerFormat.MPEG_4,      videoBitRate: 5000000,      videoFrameRate: 30,      videoWidth: 1920,      videoHeight: 1080    };    // Start transcoding    await this.transcoder.startTranscode(inputPath, outputPath, outputFormat);  }  // Pause transcoding  async pauseTranscode(): Promise<void> {    await this.transcoder?.pauseTranscode();  }  // Resume transcoding  async resumeTranscode(): Promise<void> {    await this.transcoder?.resumeTranscode();  }  // Cancel transcoding  async cancelTranscode(): Promise<void> {    await this.transcoder?.cancelTranscode();  }  // Get output path  getOutputPath(): string {    return this.outputPath;  }}

Transcoding Progress Page

The VideoTranscoderPage component manages UI state and user interactions. It initializes the transcoder manager, starts transcoding on appearance, and provides pause/resume and cancel buttons.

// entry/src/main/ets/pages/VideoTranscoderPage.ets@Entry@Componentstruct VideoTranscoderPage {  @State progress: number = 0;  @State isTranscoding: boolean = false;  @State isPaused: boolean = false;  private transcoderManager: AVTranscoderManager = new AVTranscoderManager();  aboutToAppear(): void {    this.startTranscode();  }  async startTranscode(): Promise<void> {    this.isTranscoding = true;    await this.transcoderManager.startTranscode(      'internal://cache/source.mp4',      'internal://cache/output.mp4'    );  }  build() {    Column() {      Text('Video Transcoding')        .fontSize(24)        .fontWeight(FontWeight.Bold)        .margin({ top: 50 })      // Progress bar      Progress({ value: this.progress, total: 100 })        .width('100%')        .margin({ top: 20 })      Text(`${this.progress}%`)        .fontSize(18)        .margin({ top: 12 })      // Control buttons      Row() {        Button(this.isPaused ? 'Resume' : 'Pause')          .onClick(() => this.togglePause())        Button('Cancel')          .onClick(() => this.cancelTranscode())      }      .justifyContent(FlexAlign.SpaceAround)      .width('100%')      .margin({ top: 20 })    }    .padding(16)  }  async togglePause(): Promise<void> {    if (this.isPaused) {      await this.transcoderManager.resumeTranscode();    } else {      await this.transcoderManager.pauseTranscode();    }    this.isPaused = !this.isPaused;  }  async cancelTranscode(): Promise<void> {    await this.transcoderManager.cancelTranscode();    router.back();  }}

Transcoding Completion Page

The TranscoderFinishPage receives the output path via router params and plays the transcoded video using the Video component.

// entry/src/main/ets/pages/TranscoderFinishPage.ets@Entry@Componentstruct TranscoderFinishPage {  @State outputPath: string = '';  aboutToAppear(): void {    const params = router.getParams() as Record<string, string>;    this.outputPath = params.outputPath ?? '';  }  build() {    Column() {      Text('Transcoding Complete')        .fontSize(24)        .fontWeight(FontWeight.Bold)        .margin({ top: 50 })      // Play transcoded video      Video({ src: this.outputPath })        .width('100%')        .aspectRatio(16 / 9)        .margin({ top: 20 })      // Return to home      Button('Back to Home')        .width('100%')        .margin({ top: 20 })        .onClick(() => {          router.back();        })    }    .padding(16)  }}

Transcoding Flow

1. Select video and configure parameters   ↓2. Create AVTranscoder instance   ↓3. Start transcoding   ↓4. Display transcoding progress   ↓5. Pause/Resume/Cancel available   ↓6. Transcoding complete   ↓7. Play transcoded video

Summary and Extensions

Key Points

AVTranscoder: Video transcoding management class

Transcoding Configuration: Set output format and parameters

Progress Monitoring: Listen for transcoding progress changes

Control Operations: Pause, resume, cancel transcoding

Extension Directions

Support more video formats

Add batch transcoding functionality

Implement transcoding queue

Support custom filters

Supplementary: Implementation Ideas and Considerations

1) Applicable Scenarios and Goals

Scenarios: Businesses needing reusable modules that maintain stable experience across device models and system versions.

Goals: Functional usability, controllable experience (performance/power/latency), observability (logs/metrics/error reporting), regressibility (reproducible and verifiable).

2) Core Principles

Map the input-processing-output chain: identify inputs (UI events/media streams/network data/system callbacks), key processing states (initialization, running, exception, release), and output consumption (page rendering, file persistence, callback notification, cross-device transfer). A clear chain simplifies exception handling and resource release.

3) Implementation Checklist (Suggested Order)

Define capability boundaries: separate UI-layer logic from independent modules/services to avoid bloating pages.

Handle permissions and preconditions: encapsulate permission requests and capability detection (API level/device capabilities) into reusable functions.

Establish a state machine: manage key states with enums/constants to avoid unreachable states from multiple boolean combinations.

Manage resource lifecycles: pair creation/use/release, ensuring release on exception branches (especially media, file, network connections).

Observability: instrument key phases (start/end/duration/failure reason) to minimize debugging cost.

4) Common Issues and Troubleshooting (by Probability)

Initialization succeeds but runtime fails: Verify preconditions (permissions, paths, network, device capabilities) and check for missing required callbacks.

Intermittent issues hard to reproduce: Enrich logs with context (key parameters, state, timestamps) and define clear retry/fallback strategies.

Performance fluctuations: Measure each segment (input→processing→output) to locate bottlenecks in CPU, I/O, or rendering; apply caching and batching where needed.

5) Acceptance and Regression Checklist

Functional: Main flow works + edge cases (empty data, retry on failure, permission denied, re-entry after exit).

Experience: Acceptable first-frame/response time, no noticeable stutter during continuous operation.

Stability: No resource leaks on repeated enter/exit, exception branches recover.

Compatibility: Consistent behavior across resolutions, orientations, dark mode, and API levels.

6) Extensibility Directions

Once core capability is verified, extract business policies into configuration (thresholds, retry counts, cache sizes) and add telemetry metrics (success rate, latency distribution, error code breakdown) to enable reuse across more business scenarios.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Mobile DevelopmentHarmonyOSprogress trackingArkTSvideo transcodingpause resumeMediaKitAVTranscoder
51CTO HarmonyOS Developer Community
Written by

51CTO HarmonyOS Developer Community

The HarmonyOS Developer Community is a learning-oriented community for developers to learn, communicate, ask questions, and share.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.