Code Monkey home page Code Monkey logo

fwplayer's Introduction

FWPlayer

Swift5 Version Carthage compatible License Platform

FWPlayer

A video player SDK for iOS, it is based on AVPlayer.

Features

  • Supports horizontal and vertical playback
  • Supports auto-rotating screen playback
  • Supports the full-screen and mini-player playback
  • Supports mini-player position to drag freely
  • Supports the network and local video playback
  • Supports full-screen lock
  • Supports playback while downloading (Media Cache)
  • Supports vertical slide on the left side of the screen to adjust the brightness
  • Supports the vertical slide on the right side of the screen to adjust the volume
  • Supports gesture swipe fast-forward and rewind
  • Supports drag slider fast-forward and rewind
  • Supports direct jump to a point in the timeline to play
  • Supports multiple video formats
  • Supports UITableView playback
  • Supports UICollectionView playback
  • Supports UIScrollView playback
  • Supports background playback
  • Supports play sound in silent mode by default
  • Supports speed rate playback (0.5x, 1.0x, 1.25x, 1.5x, 2.0x)
  • Supports custom player view
  • Supports advertising view
  • Supports adding Http headers and other options to AVURLAsset
  • Supports iPhone X and above
  • Supports iOS 13 +
  • FFmpeg is not supported because OpenGL ES was deprecated in iOS 12

Requirements

  • iOS 10 +
  • Xcode 11 +

Installation

You can install FWPlayer SDK in several ways:

  1. CocoaPods
  2. Carthage
  3. Manual Installation

CocoaPods

CocoaPods is an easy way to install FWPlayer.

  1. Add following pod to your Podfile:
platform :ios, '10.0'

target 'Your App' do
    pod 'FWPlayer'
end
  1. Then, run the following command:
$ pod install
  1. Switch over to Build Phases and add a New Run Script Phase by clicking the + in the top left of the editor. Add the following command to solve the issue of App Store submission.
bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/FWPlayerCore.framework/strip-frameworks.sh"

Carthage

Since FWPlayer SDK is distributed as a binary, you need to use custom binary rule in your Cartfile.

  1. Add following to your Cartfile:
binary "https://raw.githubusercontent.com/FoksWang/FWPlayer/master/Carthage/FWPlayer.json" ~> 1.0.13
  1. Fetch framework by running:
$ carthage update --platform iOS

Manual Installation

  1. Add the FWPlayer framework to Embedded Binaries for your target:
FWPlayerCore.framework
  1. Make sure you link with the following Linked Frameworks and Libraries:
FWPlayerCore.framework

Usage

Normal Style

Objective-C

FWAVPlayerManager *playerManager = [[FWAVPlayerManager alloc] init];
self.player = [FWPlayerController playerWithPlayerManager:playerManager containerView:self.containerView];
self.player.controlView = self.controlView;

Swift

private var player: FWPlayerController?

private lazy var containerView: UIImageView = {
	let imageView = UIImageView()
	imageView.setImageWithURLString(coverImageUrl, placeholder: UIImage(named: "placeholder"))
	return imageView
}()

private lazy var controlView: FWPlayerControlView =  {
	let view = FWPlayerControlView()
	view.fastViewAnimated = true
	view.autoHiddenTimeInterval = 5.0
	view.autoFadeTimeInterval = 0.5
	view.prepareShowLoading = true
	view.prepareShowControlView = true
	return view
}()

let playerManager = FWAVPlayerManager()
playerManager.isEnableMediaCache = false

// Setup player
self.player = FWPlayerController(playerManager: playerManager, containerView: self.containerView)
self.player?.controlView = self.controlView

// Setup continue playing in the background
self.player?.pauseWhenAppResignActive = true

self.player?.orientationWillChange = { [weak self] (player, isFullScreen) in
	self?.setNeedsStatusBarAppearanceUpdate()
}

// Finished playing
self.player?.playerDidToEnd = { [weak self] (asset) in
	guard let strongSelf = self else {
		return
	}
	strongSelf.player?.currentPlayerManager.replay!()
	strongSelf.player?.playTheNext()
	if strongSelf.player?.isLastAssetURL == false {
		strongSelf.controlView.showTitle("Video Title", coverURLString: strongSelf.kVideoCover, fullScreenMode: .landscape)
	} else {
		strongSelf.player?.stop()
	}
}

self.player?.assetURLs = self.assetURLs

To play the next or previous video, just set:

Objective-C

self.player.assetURLs = self.assetURLs;

Swift

self.player!.assetURLs = self.assetURLs
  • To play the next video, please call method playTheNext
  • To play the previous video, please call method playThePrevious
  • To play the video from the asset list, please call method playTheIndex:index

For example, play the next video:

Objective-C

if (!self.player.isLastAssetURL) {
    [self.player playTheNext];
    [self.controlView showTitle:@"Video title" coverURLString:kVideoCover fullScreenMode:FWFullScreenModeAutomatic];
} else {
    NSLog(@"No more videos");
}

Swift

if self.player!.isLastAssetURL == false {
    self.player!.playTheNext()
    self.controlView.showTitle("Video title", coverURLString: kVideoCover, fullScreenMode: .automatic)
} else {
    print("No more videos")
}

Quick demo for Normal Style

Step 1: In AppDelegate, make sure you have var window: UIWindow?

Swift

    var window: UIWindow?
    static var shared: AppDelegate {
        UIApplication.shared.delegate as! AppDelegate
    }

Step 2: In SceneDelegate, make sure you have var window: UIWindow?

Swift

    var window: UIWindow?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()
        AppDelegate.shared.window = window
    }

Step 3: Use quick demo code ViewController

Swift

import UIKit
import FWPlayerCore

class ViewController: UIViewController {
    
    private let kVideoCover = "https://github.com/FoksWang/FWPlayer/blob/master/Example/FWPlayer/Images.xcassets/Common/cover_image_placeholder.imageset/cover_image_placeholder.jpg?raw=true"
    private var player: FWPlayerController?
    private lazy var containerView: UIImageView = {
        let imageView = UIImageView()
        let color = UIColor(red: 220.0/255.0, green: 220.0/255.0, blue: 220.0/255.0, alpha: 1)
        let placeholderImage = FWUtilities.image(with: color, size: CGSize(width: 1, height: 1))
        imageView.setImageWithURLString(kVideoCover, placeholder: placeholderImage)
        return imageView
    }()
    
    private lazy var controlView: FWPlayerControlView = {
        let view = FWPlayerControlView()
        view.fastViewAnimated = true
        view.autoHiddenTimeInterval = 5.0
        view.autoFadeTimeInterval = 0.5
        view.prepareShowLoading = true
        view.prepareShowControlView = true
        return view
    }()
    
    private lazy var playButton: UIButton = {
        var button = UIButton(type: .custom)
        button.setImage(FWUtilities.imageNamed("FWPlayer_all_play"), for: .normal)
        button.addTarget(self, action: #selector(playButtonClick), for: .touchUpInside)
        return button
    }()
    
    @objc private func playButtonClick() {
        print("playButtonClick")
        self.player!.playTheIndex(assetIndex)
        self.controlView.showTitle("Video title 1", coverURLString: kVideoCover, fullScreenMode: .automatic)
    }
    
    private lazy var nextButton: UIButton = {
        var button = UIButton(type: .system)
        button.setTitle("Next", for: .normal)
        button.addTarget(self, action: #selector(nextButtonClick), for: .touchUpInside)
        return button
    }()
    
    @objc private func nextButtonClick() {
        print("nextButtonClick")
        assetIndex += 1
        if assetIndex > assetURLs.count - 1 {
            assetIndex = assetURLs.count - 1
        }
        self.player!.playTheIndex(assetIndex)
        self.controlView.showTitle("Video title 2", coverURLString: kVideoCover, fullScreenMode: .automatic)
    }
    
    private var assetIndex = 0
    private lazy var assetURLs: Array<URL> = {
        var assetList = [
            URL(string: "https://svt1-b.akamaized.net/se/svt1/master.m3u8")!,
            URL(string: "https://svt1-b.akamaized.net/se/svt2/master.m3u8")!,
            URL(string: "https://www.radiantmediaplayer.com/media/bbb-360p.mp4")!,
            URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4")!,
            URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4")!,
            URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4")!,
            URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/SubaruOutbackOnStreetAndDirt.mp4")!,
            URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4")!,
            URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/VolkswagenGTIReview.mp4")!,
            URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4")!,
            URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WhatCarCanYouGetForAGrand.mp4")!,
        ]
        return assetList
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        self.view.backgroundColor = .white
        self.view.addSubview(self.containerView)
        self.containerView.addSubview(self.playButton)
        self.view.addSubview(self.nextButton)
        
        let version = FWAVPlayerManager.getVersionNumber()
        let build = FWAVPlayerManager.getBuildNumber()
        print("version = \(String(describing: version)), build = \(String(describing: build))")
        
        let playerManager = FWAVPlayerManager()
        // Playback speed,0.5...2
        playerManager.rate = 1.0
        
        // Enable media cache for assets
        playerManager.isEnableMediaCache = false
        
        // Setup player
        self.player = FWPlayerController(playerManager: playerManager, containerView: self.containerView)
        self.player!.controlView = self.controlView
        // Setup continue playing in the background
        self.player!.pauseWhenAppResignActive = true
        
        self.player!.orientationWillChange = { [weak self] (player, isFullScreen) in
            guard let self = self else { return }
            self.setNeedsStatusBarAppearanceUpdate()
        }
//        playerManager.isMuted = true
        
        // Finished playing
        self.player!.playerDidToEnd = { [weak self] (asset) in
            guard let strongSelf = self else {
                return
            }
            strongSelf.player!.currentPlayerManager.replay!()
            strongSelf.player!.playTheNext()
            if strongSelf.player!.isLastAssetURL == false {
                strongSelf.controlView.showTitle("Video Title", coverURLString: strongSelf.kVideoCover, fullScreenMode: .landscape)
            } else {
                strongSelf.player!.stop()
            }
        }
        self.player!.assetURLs = self.assetURLs
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.player?.isViewControllerDisappear = false
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.player?.isViewControllerDisappear = true
    }
    
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        
        var w: CGFloat = UIScreen.main.bounds.size.width
        var h = w * 9 / 16
        var x: CGFloat = 0
        var y: CGFloat = (UIScreen.main.bounds.size.height - h) / CGFloat(2.0)
        self.containerView.frame = CGRect(x: x, y: y, width: w, height: h)
        
        w = 44
        h = w
        x = (self.containerView.frame.width - w) / 2
        y = (self.containerView.frame.height - h) / 2
        self.playButton.frame = CGRect(x: x, y: y, width: w, height: h)
        
        w = 100;
        h = 30;
        x = (self.view.frame.width - w ) / 2
        y = self.containerView.frame.maxY + 50
        self.nextButton.frame = CGRect(x: x, y: y, width: w, height: h)
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        if self.player != nil && self.player!.isFullScreen {
            return .lightContent
        } else {
            return .default
        }
    }
    
    override var prefersStatusBarHidden: Bool {
        // Support only iOS 9 and later, so return false.
        return false
    }
    
    override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
        return .slide
    }
    
    override var shouldAutorotate: Bool {
        return self.player?.shouldAutorotate ?? false
    }
    
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if self.player != nil && self.player!.isFullScreen {
            return .landscape
        }
        return .portrait
    }
}

List Style

Objective-C

FWAVPlayerManager *playerManager = [[FWAVPlayerManager alloc] init];
self.player = [FWPlayerController playerWithScrollView:self.tableView playerManager:playerManager containerViewTag:tag];
self.player.controlView = self.controlView;

Swift

let playerManager = FWAVPlayerManager()
self.player = FWPlayerController(scrollView: tableView, playerManager: playerManager, containerViewTag: tag)
self.player!.controlView = self.controlView
  • Your custom playerManager must conform to FWPlayerMediaPlayback protocol.
  • Your custom controlView must conform to FWPlayerMediaControl protocol.

Must implement in the ViewController if video rotating

Objective-C

- (BOOL)shouldAutorotate {
    return player.shouldAutorotate;
}

Swift

override var shouldAutorotate: Bool {
  return self.player?.shouldAutorotate ?? false
}

If use playback while downloading (Media Cache)

The function playback while downloading (Media Cache) does NOT support m3u8, it is commonly used for MP4.

  1. Setup isEnableMediaCache

Objective-C

playerManager.isEnableMediaCache = YES;

Swift

playerManager.isEnableMediaCache = true
  1. Setup NSAppTransportSecurity in your Info.plist
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Demonstration

ScreenShots

        

Video

FWPlayer demo

References

Author

(Foks)Hui Wang, [email protected]

License

FWPlayer is available under the MIT license. See the LICENSE file for more info.

fwplayer's People

Contributors

fokswang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fwplayer's Issues

Customize player control

Hi,

I have a couple of questions, with regards to configuring the player control view with custom icon, color, etc..

a) Currently the player control displays the download information like - 40Kb/s - Is there any way to disable that?
image

b) How to show a volume button on player control (without opening full screen)?
image

c) How can I change the player slider color & custom icon for full-screen?

Thanks.

How can i hide fullscreen button

i do not want full screen feature in app so how can i hide this button...
documentation don’t have any description about hiding this button

orientation change

how can i change orientation programatically before i start video play

tried changing this
controlView.showTitle("Video title 1", coverURLString: kVideoCover, fullScreenMode: OrientationShouldChange ? .portrait : .landscape)

but doesn't seems to work

Placeholder issue

@FoksWang
After adding the image view as a container view in the player controller. It's not showing the placeholder image just showing the black color when the video is stopped.

self.player = FWPlayerController(playerManager: playerManager, containerView: self.videoImgVw)

NSURLErrorDomain Code=-999

Error : Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://stream.SERVERDOMAIN.com/media/08d73fe3-3f8a-4c4d-b168-38f4ea6990bf/83364e09-184b-436f-b9d3-fddb0ac15335/2022-10-12-07-55-51.mp4, NSErrorFailingURLKey=https://SERVERDOMAIN.com/media/08d73fe3-3f8a-4c4d-b168-38f4ea6990bf/83364e09-184b-436f-b9d3-fddb0ac15335/2022-10-12-07-55-51.mp4

Please Note-

  1. video is 1 hour 16 min long
  2. I'm on the wifi network
  3. can play a number of videos some gets this issue
  4. QuickTime player and AVPlayer are able to play this video

Play and pause and replay at end video

  • What is code to play option
  • What is code to pause option
  • how can replay once video end display replay button after user tap then will start.
  • once slide moving it is keep on playing background audio and screen (it looks like struct)

Add sub view to player

Thanks @FoksWang for amazing video player, good job!

How can is add a subview to player? I need to have a watermark in fullscreen mode.

Background not working on iOS 14.

I've implemented with the example code in document. Enable Background Mode (for Audio, AirPlay & PIP). But player pause when I go to device home screen.
How can I achieve this feature?

Local Path

@FoksWang After changing the playback speed rate How we can get that video local path?

[Feature request] Preload

Pre-loading is a common use case these days because users expect videos to load instantly in scroll views.

API Details:

  • GLOBAL: preloadByteCount: specify how many bytes at the beginning of the URL to preload.
  • GLOBAL: queueMax: Max number of URLS in the preload queue, if this number is reached upon insertion, remove previous URLS to make space
  • DYNAMIC: networkTaskMax: Max number of concurrent network tasks for preloading at any given time. This is necessary to avoid binging client bandwidth and avoid blocking iOS threads.
  • preload(urls: Array): add the following urls to to the pre-load queue. Make space in queue if queueMax is reached. ONLY preload if:
  1. the current video playing has sufficient play buffer due to good network. If this is not the case, wait until it is to preload.
  2. the networkTaskMax has not been reached.
  • stopPreload(urls: Array): remove urls from pre-load queue and stop associated data tasks immediately. Extremely useful if user back out of page for example.

Let me know if you need help implementing these. Should be relatively straightforward.

Add option header in AVURLAsset?

HI,

Great library for video playing.

I have a question regarding setting the assetUrl in FWPlayerController.

Is there a way to add custom header in the asset url?

For example: In Avplayer we can add AVURLAssetHTTPHeaderFieldsKey using AVURLAsset.

let url = URL(string: "url")
let asset = AVURLAsset(url: url!, options: ["AVURLAssetHTTPHeaderFieldsKey" : [ "Cookie" : "tx=\(some_value)" ] ])
let PlayerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: PlayerItem)

Can't display video player in my project

Hello Mr. Wang,

I really like the sdk you created. Well done!
I wanted to include into my project but I have issues making the player visible.

Here is my code:

class UserChallengeInformationViewController: UIViewController {
...
  public var player:FWPlayerController?
       
    private lazy var controlView: FWPlayerControlView =  {
        let view = FWPlayerControlView()
        view.fastViewAnimated = true
        view.autoHiddenTimeInterval = 5.0
        view.autoFadeTimeInterval = 0.5
        view.prepareShowLoading = true
        view.prepareShowControlView = true
        return view
    }()

    func setupView() {
       ...
        challengeInfoTableView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(challengeInfoTableView)
        
        challengeInfoTableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
        challengeInfoTableView.widthAnchor.constraint(equalToConstant: width).isActive = true
        challengeInfoTableView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
        challengeInfoTableView.bottomAnchor.constraint(equalTo: self.cancelButton.topAnchor).isActive = true
       
        challengeInfoTableView.delegate = self
        challengeInfoTableView.dataSource = self
        challengeInfoTableView.register(ChallengeInfoTimeTableViewCell.self, forCellReuseIdentifier: "timeCell")
        challengeInfoTableView.register(ChallengeTitleAndDescriptionTableViewCell.self, forCellReuseIdentifier: "titleCell")
        challengeInfoTableView.register(ChallengeInfoUserTableViewCell.self, forCellReuseIdentifier: "userProfileCell")
        challengeInfoTableView.register(ChallengeInfoImageTableViewCell.self, forCellReuseIdentifier: "challengeImageCell")
        challengeInfoTableView.separatorStyle = .none
   }

   private func setupVideoPlayer() {
     let playerManager = FWAVPlayerManager()
        playerManager.isEnableMediaCache = false
        
        self.player = FWPlayerController(scrollView: self.challengeInfoTableView, playerManager: playerManager, containerViewTag: 100)
        self.player?.controlView = self.controlView
        
        // Setup continue playing in the background
        self.player?.pauseWhenAppResignActive = true
        self.player?.forceDeviceOrientation = true
        self.player?.disableGestureTypes = .pan
        
        self.player?.orientationWillChange = { [unowned self] (player, isFullScreen) in
            self.setNeedsStatusBarAppearanceUpdate()
            UIViewController.attemptRotationToDeviceOrientation()
            self.challengeInfoTableView.scrollsToTop = !isFullScreen
        }

        // Finished playing
        self.player?.playerDidToEnd = { [weak self] (asset) in
            guard let strongSelf = self else {
                return
            }
            strongSelf.player?.currentPlayerManager.replay!()
        }
   }
}

My customized **_ChallengeInfoImageTableViewCell_** looks like :
class ChallengeInfoImageTableViewCell: UITableViewCell {
    ...
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        initChallengeImageView()
    }

   private func initChallengeImageView() {
        challengeImageView = UIImageView()
        challengeImageView!.translatesAutoresizingMaskIntoConstraints = false
        addSubview(challengeImageView!)
        
        challengeImageView!.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        challengeImageView!.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        challengeImageView!.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        challengeImageView!.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        challengeImageView!.contentMode = .scaleAspectFill
        challengeImageView!.clipsToBounds = true
        challengeImageView!.isUserInteractionEnabled = true
        challengeImageView?.tag = 100 // SAME TAG AS IN THE VIEW CONTROLLER
}

When playing the video, I can hear the sound, but I can't see anything. Nothing pops up.
Do you have an idea why? Thanks in advance!

How to place controlView inside the safe area

Hello Mr. Wang

FWPlayer SDK is great, Our team want to include into our vlog project.
But in my project, the controlView is displayed out than safe area.
Ps: The example is work well.

IOS Target: 14.0

image

Can you help me?
Thanks in advance!

I Have some common Issue please fix it or implement

  1. Feature -> Supports advertising view (How i will do with this player ?)
  2. Feature -> AVMediaTypeText, AVMediaTypeSubtitle (How to implement ?)
  3. Feature -> How to show mini player without (Scrollview , TableView and CollectionView)
  4. Supports the vertical slide on the right side of the screen to adjust the volume (Not working in Portrait mode)

Disable Specific Pan Actions

I am looking to disable the volume pan option & disable the brightness pan. I would also like the option to allow one or the other or maybe disable for portrait / landscape mode.

Thanks.

Laggy video on iPhone 8

There is some lags in iPhone 8 (iOS 14.2) when a video plays for the first time. I think you should set the 'automaticallyWaitsToMinimizeStalling' if it is not. The caching process is helping me so much so if you help me on this issue too that would be wonderful.

Status Bar issue

@FoksWang
first of all Thank you for this library
after I have installed the FWPlayer from pod {pod 'FWPlayer', '~> 1.0.13'}
the status-bar become white always ,
how can I stop the library from control for status bar color because I have two theme (two mode) on my app (dark and light mode) ,
before install FWPlayer everything's fine , but after install it I have this issue
Before , After

[Request] Compile for arm64e & more info for Objective-C usage

Hi there, am trying to use your FWPlayer framework on jailbroken arm64e device so can you please add support to arm64e?

also can you please update README with more info for Objective-C usage as I don't know Swift language and there is a lot going on in Swift usage that is missing in Objective-C usage which I would appreciate it if you update README with more Objective-C usage info

Thank you very much

Full screen button

I want to trigger action when user tap on view fullscreen. can anyone tell how to do that.
Thank.

[BUG] Audio session is being configured regardless

Although I marked customAudioSesson = true, the library is still configuring the shared audio session. This is messing with the audio session and bugging other parts of my app. Why is this occurring?

Separate topic: why is the source code all executable? How can I change parts of the library?

unrecognized selector sent to instance error


import UIKit
import FWPlayerCore

class ViewController: UIViewController {
    
    private var player: FWPlayerController?
    let playerManager = FWAVPlayerManager()
    
    @IBOutlet weak var containerView:UIImageView!
    //@IBOutlet weak var containerView:UIImageView!
    
    @IBOutlet weak var controlView: FWPlayerControlView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        controlView.fastViewAnimated = true
        controlView.autoHiddenTimeInterval = 5.0
        controlView.autoFadeTimeInterval = 0.5
        controlView.prepareShowLoading = true
        controlView.prepareShowControlView = true
        
        playerManager.isEnableMediaCache = false
        
    
    }
    
    @IBAction func button(_ sender: Any) {
        // Setup player
            self.player = FWPlayerController(playerManager: playerManager, containerView: self.containerView)
            self.player?.controlView = self.controlView
            
            // Setup continue playing in the background
            self.player?.pauseWhenAppResignActive = true
            
            self.player?.orientationWillChange = { [weak self] (player, isFullScreen) in
                self?.setNeedsStatusBarAppearanceUpdate()
            }
            
            // Finished playing
            self.player?.playerDidToEnd = { [weak self] (asset) in
                guard let strongSelf = self else {
                    return
                }
                strongSelf.player?.currentPlayerManager.replay!()
                strongSelf.player?.playTheNext()
                if strongSelf.player?.isLastAssetURL == false {
                    strongSelf.controlView.showTitle("Video Title", coverURLString: nil, fullScreenMode: .landscape)
                } else {
                    strongSelf.player?.stop()
                }
            }
            
            var urls = [URL]()
        guard let url = URL(string: "https://www.radiantmediaplayer.com/media/big-buck-bunny-360p.mp4") else { return }
        urls.append(url)
        print(urls)
        self.player?.assetURLs = urls
            
    }
}

lovely player but i coudn't use it as well. will you help me ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.