I wanted to implement a video quality control in video player in swift.I have used preferredPeakBitRate of avplayer item but I am not able to change the quality of video while the video is playing.I have the manifest file URL that contains different bit rates of video.Kindly suggest me any third party video player that used manual video quality control or tell me how I can achieve using avplayer in swift.
Related
I am working on video player app which streams video from m3u8 url.
Due to apple limitation, I can't set specific video quality during playtime or startup. I am curious because i can see this feature supported in Youtube iOS app.
Apple provides preferredPeakBitRate but it doesn't guarantee whether video will be played in that bitrate.
How do youtube able to achieve that video quality or maintaining specific video quality in iOS?
Just let me know if i am doing anything wrong or missing anything. Thanks in advance
The main source of my worries comes from the m3u8 manifests I use to play video in my app.
They contain variants with audio & video and some containing only audio.
The problem occurs when I load this type of manifest in avplayercontroller/avplayer while having a bad network or low bandwidth.
In every case avplayer witch to the tracks with no video to clear some bandwidth, resulting in no image appearing on the player.
I would like to know if there is a way to force avplayer or avplayercontroller to only focus on the manifest tracks containing audio and video and forbid audio only tracks to be selected, loaded, and played.
Thank you in advance to any tips or pointers you can give me on this subject.
I am using AVPlayer to play a video from an https url with a setup this:
player = AVPlayer(url: URL(string: urlString))
player?.automaticallyWaitsToMinimizeStalling = false
But since the video is a little long, there is a short blank screen delay before the video actually starts to play. I think this is because it is being loaded from https.
Is there anyway to remove that delay by making AVPlayer play the video right away without loading the whole thing?
I added .automaticallyWaitsToMinimizeStalling but that does not seem to make a difference.
If anyone has any other suggestions please let me know.
I don't think there is nothing to do with loading from https. what is your video file format? I think you are thinking of adaptive bitrate streaming behavior.
https://en.wikipedia.org/wiki/Adaptive_bitrate_streaming#Apple_HTTP_Live_Streaming
HTTP Live Streaming (HLS) is an HTTP-based media streaming
communications protocol implemented by Apple Inc. as part of QuickTime
X and iOS. HLS supports both live and Video on demand content. It
works by breaking down streams or video assets into several small
MPEG2-TS files (video chunks) of varying bit rates and set duration
using a stream or file segmenter. One such segmenter implementation is
provided by Apple.[29] The segmenter is also responsible for producing
a set of index files in the M3U8 format which acts as a playlist file
for the video chunks. Each playlist pertains to a given bitrate level,
and contains the relative or absolute URLs to the chunks with the
relevant bitrate. The client is then responsible for requesting the
appropriate playlist depending on the available bandwidth.
For more information about HTTP Live Streaming
https://developer.apple.com/documentation/http_live_streaming
This tutorial includes some experiments on HTTP Live Streaming version and Non-HTTP Live Streaming version.
https://www.raywenderlich.com/5191-video-streaming-tutorial-for-ios-getting-started
Have you tried using AVPlayerItem's preferredForwardBufferDuration? You can manage how long AVPlayer continues to buffer using this property.
player.currentItem?.preferredForwardBufferDuration = 1
From Apple's own documentation:
The duration the player should buffer media from the network ahead of the playhead to guard against playback disruption.
This property defines the preferred forward buffer duration in seconds. If set to 0, the player will choose an appropriate level of buffering for most use cases. Setting this property to a low value will increase the chance that playback will stall and re-buffer, while setting it to a high value will increase demand on system resources.
Suggestion:
As a video is streaming, we are also relying on a network connection. So for poor network connection, It always has a chance to display a blank screen.
We can do like, We can fetch thumbnail of streaming video on the previous screen from the server or can generate thumbnail from application side from streaming URL. When streaming screen open, display thumbnail to a user with streaming indicator and when video starts streaming hide thumbnail.
In that particular case you can place an UIImageView above to the AVPLayerlayer view.
That image work as a landscape/cover image of your video which matched the first frame of your video along an UIActivityIndicator on subview.
Now hide that image when video got about to play.
This helps to hide the black frame of your video as it inevitable to handle the initial buffer state of the video.
How can I change Video Quality like YouTube?
Currently, I am playing with original quality and I am giving options like 360p, 480p, 720p for changing quality.
How can I change it?
You cant do that simply with AVplayer. you require diffrent URL for different quality video. When user select other quality, you can switch to that video with replaceCurrentItemWithPlayerItem method fo AVPlayer.
AVPlayerItem *playeriem= [AVPlayerItem playerItemWithURL:urlOfSelectedQualityVideo];
[playeriem seekToTime:player.currentTime];
[player replaceCurrentItemWithPlayerItem:playeriem];
In order to do such things like converting video you should use FFmpeg library.
Try to look for some libraries that use ffmpeg on github.
Like this one: https://github.com/iMoreApps/ffmpeg-avplayer-for-ios-tvos
You can't do that with AVPlayer. When just streaming you use M3U index files, TS files containing the video data and just switch streams.
Check out Apple's HLS Documentation and playlist Examples.
You can also create multiple renditions of m3u8 one with lower quality video bitrates say 128k to 650k and another one with 650k + to higher bitrates and use a higher quality stream URL suggested in the answer above
AVPlayerItem *playeriem= [AVPlayerItem playerItemWithURL:urlOfSelectedQualityVideo];
I am developing an application which require to apply audio effect on recorded video.
I am recording video using GPUImage library. I can successfully done with it. Now, I need to apply audio effect like Chipmunk, Gorila, Large Room, etc.
I looked into Apple's document and it say that AudioEngine can't apply AVAudioUnitTimePitch on Input Node (as Microphone).
For solving this problem, I use following mechanism.
Record video & audio at same time.
Play video. While playing video, start AudioEngine on Audio file and apply AVAudioUnitTimePitch on it.
[playerNode play]; // Start playing audio file with video preview
Merge video and new effected audio file.
Problem :
User have to preview a full video for audio effect merge. This is not a good solution.
If I set volume of playerNode to 0 (zero). Then It record mute video.
Please provide any better suggestion to do this things. Thanks in advance.