# WMPlayer: an AVPlayer wrapper whose CocoaPods path has two fallbacks

> WMPlayer is an Objective-C view that wraps AVPlayer for iOS, distributed through CocoaPods, with a feature list covering gestures, Picture in Picture, background playback and speed control. Its documentation is a checked feature list plus two samples, and it ends by asking for bugs over WeChat.

**zhengwenming/WMPlayer** — GitHub describes it as WMPlayer: a wrapper around AVPlayer that subclasses UIView, supports CocoaPods, gesture-based fast-forward/rewind, full adaptation for notch screens, and playback of both network and local video. The repository metadata lists Objective-C as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

- Repository: https://github.com/zhengwenming/WMPlayer
- Stars: 3,271 · Forks: 760
- Language: Objective-C
- License: MIT
- Published: 2026-08-13 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/zhengwenming-wmplayer

## A UIView around AVPlayer, documented as a checklist of nineteen boxes

The component is a UIView subclass that wraps AVPlayer, and the documentation for it is a list of ticked boxes rather than an API description. Rotation is handled in both directions with automatic detection on device rotation. Playback sources are network streams, local files, and videos picked from the system photo library, plus a cell and list playback mode. The gesture set covers brightness on the left half of the screen, volume on the right half, swipe and slider seeking, and tapping the slider to jump to the tapped position, along with jumping straight to a given time point. Also on the list are full screen lock, background playback, mute, loop playback, Picture in Picture, dynamic changes to the player's fill mode, and speed control at 0.5X, 1.0X, 1.25X, 1.5X and 2X. One entry is a behaviour rather than a feature: playing the same resource from a list into a detail view without an interruption, compared to what Toutiao does.

## pod search reportedly returns 3.0.6 while the instructions want 5.0.0

The install notes are a numbered troubleshooting ladder rather than a single command, and they open with a version mismatch. Running `pod search WMPlayer` and getting version 3.0.6, or getting nothing at all, is the failure the steps are written around. The prescribed fix is to move the Mac's Ruby to 2.4.x and CocoaPods to V1.5.3, following an article on an external blog for the upgrade procedure rather than any documentation inside the repository. From there the normal path is to put `pod 'WMPlayer'` into the Podfile and run `pod update`, and if that resolves to version 5.0.0 the notes consider it done. The second path bypasses the registry entirely and points at GitHub:

```
pod 'WMPlayer',  :git => 'https://github.com/zhengwenming/WMPlayer.git'
```

So a reader has two registries to choose between, and the guidance for telling them apart is a version number. Neither path pins anything, and both resolve to whatever the remote side currently serves.

## Both samples lay out with Masonry, and the pod line never mentions it

The network playback sample builds the model, allocates the view, adds it as a subview, and constrains it to a 9:16 box using Masonry:

```
WMPlayerModel *playerModel = [WMPlayerModel new];
playerModel.title = self.videoModel.title;
playerModel.videoURL = [NSURL URLWithString:@"http://static.tripbe.com/videofiles/20121214/9533522808.f4v.mp4"];
WMPlayer * wmPlayer = [[WMPlayer alloc]initPlayerModel:playerModel];
[self.view addSubview:wmPlayer];
[wmPlayer mas_makeConstraints:^(MASConstraintMaker *make) {
    make.leading.trailing.top.equalTo(self.view);
    make.height.mas_equalTo(wmPlayer.mas_width).multipliedBy(9.0/16);
}];
[wmPlayer play];
```

The constraint block calls `mas_makeConstraints:` with a `MASConstraintMaker`, so Masonry has to be present in the host project. The install section never says so. It names one pod, WMPlayer, and stops there, which means the reader who follows the install notes literally ends up with a sample that will not compile, and the fix is to notice the missing header rather than to find it stated.

## Two creation entry points for the same view, and a file URL round tripped through a string

The two samples do not agree on how the view is created. The network sample calls the instance initialiser `initPlayerModel:`, while the local sample calls the class method `+playerWithModel:`. Both then produce something you add as a subview and constrain to 9:16, so the difference is invisible until you copy one sample over the other and the selector is missing. The local sample also builds its URL the long way round. It creates a file URL with `+fileURLWithPath:` from a bundle resource path, asks that URL for its `absoluteString`, and feeds the resulting string into `+URLWithString:` before assigning it to `videoURL`. That converts a filesystem path into a percent escaped URL string and parses it straight back, which works but means the model holds a string rather than the file URL that was just built. The sample also ends partway through its final call, with the play step left unfinished, so the tail of that snippet has to be taken from the demo project.

## The sample stream is cleartext http dated 2012, and caching lives in another project

The URL in the network sample is `http://static.tripbe.com/videofiles/20121214/9533522808.f4v.mp4`. Three things stand out. It is plain http rather than https, which app transport security rejects by default in a modern iOS project, so a sample copied today needs the exception or a different URL before it will play anything. The path carries the date 20121214, so the asset is from the era the component was written in and its continued availability is not something this repository controls. And caching is explicitly not part of the component: the page sends anyone who wants video cached to disk to a separate open source project, KTVHTTPCache, maintained by ChangbaDevs. That division is a reasonable choice for a view wrapper, but it means two repositories have to be tracked together if you want buffered seeking over a weak connection.

## Full screen is three approaches and the first one is documented as unmaintained

Rotation gets the longest treatment on the page, split into three techniques with a named app as the example of each. Rotating the view means turning the player 90 degrees, giving it the screen's width and height, removing it from its parent and re-adding it to the window inside the rotation notification, which produces the appearance of full screen. NetEase News is the case given, and its code is described as low quality and no longer maintained, with the note that the capability is still supported and that a developer should implement it themselves or read code from before version 5.0. Two bugs are named for it: the status bar does not follow into landscape, and the keyboard and UIAlertView still present in portrait. Rotating the view controller is the second technique, attributed to Tencent Video, and it requires enabling the other three orientations in the project settings. The third is a custom transition, attributed to the iQiyi client, implemented in the demo's Sina tab detail controller, where the full screen button needs a click handler attached or it does nothing when tapped.

## Pods/ and a .DS_Store are committed, and there are no tagged releases

The root of the tree is worth reading as a snapshot of how the project is worked on. It contains `Pods/` alongside `Podfile` and `Podfile.lock`, so the resolved dependency tree is checked in rather than resolved on each clone, which makes the demo build reproducible but also means the vendored version of Masonry and anything else the demo pulls is whatever it was at commit time. A `.DS_Store` sits at the root too, the macOS Finder metadata file that no repository wants to carry. There are two `.gitattributes` files, one named plainly and one named `ObjectiveC.gitattributes`, which is the older filename for the same purpose. Licensing is MIT with a `LICENSE` file at the root. There are no tagged releases at all, so the 5.0.0 the install notes talk about is the pod registry's version rather than a release you can inspect here. The repository was last pushed on 2025-04-18, and the page closes by asking readers to contact the author directly with any bugs.

## Conclusion

WMPlayer suits a team maintaining an older Objective-C iOS codebase that wants rotation handling and seek gestures without wiring AVPlayer by hand, and that is already on CocoaPods and Masonry. Three things to check before adopting it. The install notes assume a CocoaPods and Ruby pairing from an earlier era and work around a registry result of 3.0.6, so confirm the version you actually resolve. Local caching is not in this repository at all; it points at a separate project by ChangbaDevs. And the repository was last pushed on 2025-04-18, with no tagged releases, so the page asking readers to report bugs directly to the author is the whole of the support story. If you are starting new work, the Swift-era options are a different evaluation, and the page says nothing about them.

## FAQ

### What is WMPlayer for iOS?

A UIView subclass that wraps AVPlayer, distributed through CocoaPods. The documented feature list covers network and local playback, videos from the system photo library, cell and list playback, brightness and volume gestures on the left and right halves of the screen, slider and swipe seeking, jump to a time point, full screen lock, background playback, mute, loop, Picture in Picture, fill mode changes, and speeds from 0.5X to 2X.

### How do I install WMPlayer with CocoaPods?

Put `pod 'WMPlayer'` in the Podfile and run `pod update`. If `pod search WMPlayer` reports version 3.0.6 or finds nothing, the notes say to move the Mac's Ruby to 2.4.x and CocoaPods to V1.5.3 first. If the registry path still fails, use the git source form pointing at the GitHub repository instead. Both samples also lay out with Masonry, which the install notes never mention.

### Does WMPlayer cache videos locally?

Not in this repository. The page states that for a third party library covering caching video to local storage you should use KTVHTTPCache, an open source project maintained by ChangbaDevs. WMPlayer itself is the playback view, so adopting buffering means tracking two repositories.

### How do I get WMPlayer into full screen video?

Three approaches are described. Rotate the view 90 degrees and move it to the window on rotation, whose sample code is called low quality and no longer maintained and which is noted to leave the status bar and keyboard in portrait. Rotate the view controller instead, which needs the other three orientations enabled in the project settings. Or present a full screen controller with a custom transition, as the demo's detail controller does, where the full screen button needs a click handler or tapping it does nothing.

### What playback speeds does WMPlayer support?

Five steps are on the feature list: 0.5X, 1.0X, 1.25X, 1.5X and 2X. Related toggles on the same list are mute, loop playback, and dynamic changes to the player's fill mode. The page does not document the property names behind any of these.

## Sources

- [Official README](https://github.com/zhengwenming/WMPlayer#readme)
- [Project repository](https://github.com/zhengwenming/WMPlayer)
- [README](https://github.com/zhengwenming/WMPlayer/blob/master/README.md)
- [Releases](https://github.com/zhengwenming/WMPlayer/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/zhengwenming-wmplayer
