My Current Setup (Subject to Change)
I have a simple iOS app right now that plays an M3U8 using AVPlayer. In order to place custom UI elements on top of the player (text alerts, mostly) I jimmy-rigged what is probably a terrible architecture, and I'm open to the idea of scrapping the whole thing and starting over.
First I created a new UIView which I called "MyPlayer". This UIView has a XIB file with nothing in it
Next I created a new NSObject (now UIView) which I called "PlayerDisplay". This class also has a XIB file associated with it, which contains an ImageView and a Label
In MyPlayer.m's init method, I instantiate a PlayerDisplay using an initWithMyPlayer method
In PlayerDisplay.m's initWithMyPlayer method, I created an AVPlayerViewController instance
I called [myPlayer addSubview:controller.view] and controller.view.frame = myPlayer.bounds to get the player to display within my view
I called [[NSBundle bundleForClass:[self class]] loadNibNamed:#"PlayerDisplay" owner:self options:nil] to load the XIB with the ImageView and Label
I called [myPlayer addSubview:self.contentView] and self.contentView.frame = myPlayer.bounds to get the player to display my ImageView and Label over top of the player
It felt hack-y at the time, and it feels hack-y now. But it allows me to insert a single MyPlayer view into an app and have it load all of my custom control and display logic. And it works (at least as far back as iOS 8, which is the oldest I've tested, and as far forward as iOS 12.4, which is the newest I've tested)
However I recently wanted to look into creating custom controls and looked to some industry leaders for inspiration (Netflix, YouTube, etc) - and I noticed that every other video player on the market looks the same, but none of them look like mine.
Netflix
ESPN
Hulu
Amazon Prime
YouTube
Twitch
Every one of these players has:
White icons with transparent backgrounds placed directly on top of the video (no control bar background)
A play/pause button in the dead center of the video
Seek back/forward buttons on either side of the play button
A seek bar at the bottom of the video
A single icon in the top-left
A horizontal list of icons in the top-right
Not only that, but Netflix and ESPN use the exact same icon set seek icons (although upon further inspection, the play buttons and cast buttons differ slightly)
Similarly, Hulu and Amazon Prime use the exact same icon set It was pointed out that Hulu and Amazon Prime differ sufficiently to be different icon sets. I still stand by Netflix and ESPN having identical seek buttons, though. I've rearranged the pictures to make this more obvious
It's too unbelievable to me that every single company disabled the default controls, built their own user interface from scratch, and they all just so happened to look identical. I feel like either AVPlayer has an option to enable this layout, Apple provides a framework for building UIs from icon sets which lays things out in this manner, or there may be a third-party library that is considered the "de facto" standard for video streaming, much like ExoPlayer is the leading name on Android
Compare and contrast all of the above players with my player, which is using Apple's default UI for an AVPlayerViewController:
The control bar has a background color and rounded corners
The play button is within the control bar
There are no seek forward / back buttons
There's only a volume control in the top right instead of a list of icons
How do I make my player look like theirs?
Is there just a flag in AVPlayer to say "use the other UI"? Is there a third-party library I should be using? What am I doing differently from all of the big names?
Note: I did discover AVPlayerViewControlsStyle, which I should theoretically be able to utilize with avPlayerView.controlsStyle = ..., however as you can tell from my setup above - I don't actually have an instance of AVPlayerView. Just my own custom view and the AVPlayerViewController. I tried typing controller.view.controlsStyle into Xcode to see if it would auto-complete, but it did not - making me think I don't have an AVPlayerView at all
Second Note: I also saw AVPlayerLayer when looking through the official Apple docs. What is that used for? Should I be utilizing it?
Related
I would like to have a bar/button at the bottom of my screen that behaves like the mini player bar on Spotify. If I click on it, a view appears from the bottom. If I drag it, I can play with it and make it go up and down. And if I release it, it continues up by itself.
I checked that question: How to animate an object vertically with touch like Spotify's music player does when tapping the song, but it only resizes an (image) view where I want to put a new ViewController (and I cannot drag it, only click it).
I found a project that does that: https://github.com/andriirogulin/ARSlidingPanel and it looks like it works pretty well. It is really something like that that I want to achieve.
My problem is that I have almost no knowledge of objective-C. Moreover I tried to follow the Integration tutorial and I cannot add a custom segue from ARSPContainerController. I need to drague it from an object, and there is none in the sample project. Therefore I would like to know if:
there is a name for this kind of specific bottom bar (for easier research purposes) and the way I would like to use it.
there is a Pod/project that does that in swift.
someone has a sample project that has this behaviour?
Isn't it very close to what Apple Music is doing? If so, you might be able to use this: https://github.com/xxxAIRINxxx/MusicPlayerTransition
I want to create a simple game, and as I understand it OpenGL will make that happen but could I make the menu, high score list and every thing except the game with regular xcode?
For instance, for Windows Phone (where im comming from) you could create XAML/DirectX where you totally could make the menu in xaml/cs and then the game in directx
Yes, the main view element in iOS is called an UIView and you use it to present openGL content on it. This results in being able to overlay it with any other views, subviews, put it in a superview, have multiple views with openGL content... All the events such as touches work as well. In summery implementing openGL in iOS UIView will simply override the visual content of the view leaving rest of the functionality as it is.
I have a MPMoviePlayerController instance in my iOS app, that plays a local file in fullscreen mode. This all works fine, but now I want to add a custom button to the window for changing the playback speed. We support both iPhone and iPad in all orientations.
I know how to set the playback speed from code (using setCurrentPlaybackRate), but I need to let the user do it while watching the video, which means adding some kind of button to the playback screen next to the existing buttons, e.g. next to "play", "pause", or in the top bar.
By looking on StackOverflow I have found various replies for questions similar but not quite the same, some saying it cannot be done in fullscreen, some saying it can be done (but is very complex) by creating some kind of overlay, effectively replacing the entire overlay with a custom one.
Although, I have yet to find any code examples (apart from a few snippets without context), getting-started style tutorial or similar for this, so any pointers to example code would be greatly appreciated.
maybe this Apple example could help you
https://developer.apple.com/library/ios/samplecode/MoviePlayer_iPhone/Introduction/Intro.html
I want to remove/hide the full screen button from MPMoviePlayerController standard controls as full screen mode is creating lot of problems and also not a requirement of my app.I just want the play,stop,forward,reverse controls. Can anybody help me?
There's no standard way to do this. Here are your options.
You could set the MPMoviePlayerController's controlStyle to None and create your own custom controls. Cons: this is a lot of work.
You could use the NSNotificationCenter to intercept the MPMoviePlayerWillEnterFullscreenNotification and immediately set fullScreen mode to NO. Cons: based on the iOS version of the user, this may cause a flicker or some glitchy effect.
You could go through the MPMoviePlayerController view's subviews until you get to a MPInlineTransportControls view which contains the controls, the slider and the play/pause button and the full screen button which are all of class MPTransportButton. Find that one and you can hide it or remove it from its superview. Cons: as of right now this passes app store reviews and works perfectly on all currently supported iOS versions. But this could change at any time. If Apple decides to redo their default video player you may end up with non working code.
a design / architectural question on airplay.
I have setup an external display in the AppDelegate:
UIScreen *externalScreen = UIScreen.screens.lastObject;
self.externalWindow = [[UIWindow alloc] initWithFrame:externalScreenFrame];
self.externalWindow.screen = externalScreen;
self.externalWindow.backgroundColor = [UIColor redColor];
Works fine, TV shows an empty screen in red.
Now I have a ViewController with a bunch of subviews, and one view should be shown on the device and the external screen. If I try this in ViewController.m:
[_appDelegate.externalWindow addSubview:self.deviceAndTVView];
deviceAndTVView will only show on the external screen, not on the device anymore.
What I would need is to have deviceAndTVView on the device, updating itself on touches / user interaction, and mirror those updates on the external screen.
Which is the right path to accomplish that?
Thanks for reading!
m
The technology called AirPlay mirroring is poorly named. It actually operates in two modes, one where the entire iOS device is mirrored to the AirPlay device, and in another mode where once the mirroring AirPlay device is connected, the developer has two UIWindow/UIScreen's to work with.
You are using the latter mode, which is often referred to as "mirroring", but really you have a completely separate window/screen to manage and there should be better terminology to refer to this mode of operation.
What you describe doing above is basically moving a UIView from the device window to the AirPlay window, and it's working exactly as it should!
There is no technical way for you to have a single instance of a UIView show on both of these windows - it will exist in one UIView hierarchy or the other, but not both at the same time. In other words, if you want the same thing to show on both screens, you need to create two instances of the same UIView, and add them respectively to the two windows, and then update both of them as they change.
While this may not be the super-convienent "mirroring" you were expecting, it's probably be a good thing because your UIView may have different aspect ratio on the device than it does on the AirPlay device. By having two different views, showing the same content, you can adjust the sizing of the AirPlay view to best use of the available resolution of the device.
I can think of a couple of ways of doing this. Have you looked at using KVO for this? Both the local and external views could observe whatever model or controller is driving their content.