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.
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/UseAVTranscoderVideoFunction 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 transcodingCore 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 videoSummary 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
51CTO HarmonyOS Developer Community
The HarmonyOS Developer Community is a learning-oriented community for developers to learn, communicate, ask questions, and share.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
