How Hema Achieved TikTok‑Level Short‑Video Playback Speed on iOS
To align Hema’s app short‑video experience with leading platforms like Douyin, the team introduced a proxy‑based caching layer, pre‑loading mechanisms, m3u8 handling, bitrate and resolution optimizations, dual‑player strategies, and audio controls, resulting in significantly reduced playback latency and smoother user interaction across iOS devices.
Overview
Short video content has become a new activation point for the Hema app, attracting increasing attention and investment because it can boost user stickiness and dwell time. Hema therefore launched a full‑chain video‑content strategy to improve product expression.
Optimization Effects Comparison
Tests on an iPhone 6S showed that Douyin starts playing the next video instantly after a swipe, while the pre‑optimization Hema app displayed a cover image before playback, causing a noticeable jump. After optimization, Hema’s playback latency approached Douyin’s.
Latency was measured by recording the time from full page display to the first frame rendering using frame‑by‑frame screen capture.
Other hard metrics such as playback success rate, stutter rate, and start‑up rate were also improved.
Optimization Scheme
The team studied many internal solutions, most of which integrated the Taobao player based on the open‑source ijkPlayer. Because the player layer is complex and already well‑optimized, the focus shifted to upper‑layer business pre‑loading strategies.
Unified Video Proxy and Cache
Video loading speed largely depends on network download time. Introducing a proxy server to handle video download and caching can greatly accelerate second‑playback. The proxy intercepts the original video URL, replaces it with a local proxy URL (127.0.0.1), and routes the request through the proxy module for parsing, cache reading, or remote fetching.
Before optimization:
After optimization:
The business layer encrypts the original videoUrl, replaces it with the proxyUrl, and lets the proxy module resolve, cache, or request the video before returning data to the player.
This independent proxy also benefits non‑Taobao‑player scenarios, such as Flutter system players, and includes cache size protection and periodic cleanup when the app returns to the foreground.
Proxy for m3u8
In addition to MP4, Hema frequently encounters m3u8 streams, which deliver a playlist rather than a raw video stream. The solution rewrites every URL in the playlist to a proxy URL, ensuring the entire stream passes through the proxy.
Previously, only the first segment’s URL was replaced, causing crashes when later segments referenced the original relative URLs. The fix replaces all URLs with full proxy paths.
Independent Preload Capability
While proxy caching speeds up second playback, the first playback still suffers from download latency. An independent preload API HMVideoLoader preLoadUrls:URLS downloads video data (up to 1 MB per URL) in a serial manner to avoid bandwidth saturation. When the user scrolls to the video, playback can start immediately.
If the user begins playing a video that is currently preloading, the preload task is cancelled to prevent duplicate downloads.
static NSString * const VIDEO_HD = @"hd");
static NSString * const VIDEO_SD = @"sd");
static NSString * const VIDEO_LD = @"ld");
static NSString * const VIDEO_HD_H265 = @"hd_265");
static NSString * const VIDEO_SD_H265 = @"sd_265");
static NSString * const VIDEO_LD_H265 = @"ld_265");
+ (NSArray *)getExpectedVideoDefinition {
NSArray *VIDEO_PRIORITY_GOOD_ENV = nil;
NSArray *VIDEO_PRIORITY_NORMAL_ENV = nil;
NSArray *VIDEO_PRIORITY_BAD_ENV = nil;
if ([[[UIDevice currentDevice] systemVersion] compare:@"11.0" options:NSNumericSearch] == NSOrderedAscending) {
VIDEO_PRIORITY_GOOD_ENV = @[VIDEO_HD, VIDEO_SD, VIDEO_LD];
VIDEO_PRIORITY_NORMAL_ENV = @[VIDEO_SD, VIDEO_LD, VIDEO_HD];
VIDEO_PRIORITY_BAD_ENV = @[VIDEO_LD, VIDEO_SD, VIDEO_HD];
} else {
VIDEO_PRIORITY_GOOD_ENV = @[VIDEO_HD_H265, VIDEO_SD_H265, VIDEO_LD_H265];
VIDEO_PRIORITY_NORMAL_ENV = @[VIDEO_SD_H265, VIDEO_LD_H265, VIDEO_HD_H265];
VIDEO_PRIORITY_BAD_ENV = @[VIDEO_LD_H265, VIDEO_SD_H265, VIDEO_HD_H265];
}
AliHADeviceEvaluationLevel deviceLevel = [AliHADeviceEvaluation evaluationForDeviceLevel];
NetworkQualityStatus networkQualityStatus = [[NWNetworkQualityMonitor shareInstance] currentNetworkQualityStatus];
NetworkStatus nwStatus = [[NWReachabilityManager shareInstance] currentNetworkStatus];
NSArray *videoPriority = VIDEO_PRIORITY_NORMAL_ENV;
if (networkQualityStatus == SEMP_StrongSemaphore) {
if (deviceLevel == HIGH_END_DEVICE) {
videoPriority = VIDEO_PRIORITY_GOOD_ENV;
} else {
if (nwStatus == ReachableViaWiFi) {
videoPriority = VIDEO_PRIORITY_NORMAL_ENV;
} else {
videoPriority = VIDEO_PRIORITY_BAD_ENV;
}
}
} else {
if (deviceLevel == HIGH_END_DEVICE || deviceLevel == MEDIUM_DEVICE) {
videoPriority = VIDEO_PRIORITY_NORMAL_ENV;
} else {
videoPriority = VIDEO_PRIORITY_BAD_ENV;
}
}
return videoPriority;
}Bitrate and Resolution Optimization
Hema originally used H.264 high‑definition videos, which are often larger than needed for feed streams. After enabling H.265 transcoding on cloudVideo, three resolutions (HD, SD, LD) are available.
Size comparison:
H.264 HD 10.6 MB → H.265 HD 7.1 MB (≈30 % reduction)
H.264 HD 21 MB → H.265 SD 8.3 MB (≈60 % reduction)
Server APIs now return H.265 URLs; iOS uses H.265 on iOS 11+ and falls back to H.264 on older versions.
Immersive Video Paging Optimization
Even after the above improvements, the first frame of the next immersive video still lagged ~200 ms due to player initialization and network latency. To achieve TikTok‑like smoothness, a dual‑player strategy was adopted: while the current video plays, a second player pre‑loads the next video’s first frame and pauses. When the user swipes, playback resumes instantly without showing a cover image.
First Video Load Optimization
The first video on an immersive page cannot benefit from pre‑loading because there is no prior opportunity to fetch it. The new strategy passes the videoUrl from the previous page, initiates playback immediately, and concurrently sends the mtop request for business data, allowing video and data to load asynchronously.
Audio Experience Optimization
Audio handling was also refined:
App launch does not interrupt background music.
Entering dedicated audio/video pages pauses background music.
Leaving the app or moving to background resumes music.
Audio playback ignores the hardware mute switch, similar to Douyin.
Future Directions
Planned work includes further encapsulation of player logic, seamless playback‑progress transfer between pages, performance tuning for simultaneous multi‑video playback, converting videos to GIFs for preview in high‑density scenarios, and adding speech‑to‑text subtitles for better product expression.
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.
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.
