Giter Site home page Giter Site logo

ksplayer's Introduction

Build Status Platform License

KSPlayer

KSPlayer is a powerful media play framework for iOS, tvOS, macOS, xrOS, visionOS, Mac Catalyst, SwiftUI, Apple Silicon M1 .

English | 简体中文

Based On

  • FFmpeg
  • Metal
  • AVAudioEngine

Features

  • iOS, tvOS, macOS, visionOS, Mac Catalyst, Apple Silicon M1, SwiftUI.
  • Multiple audio/video tracks.
  • hardware accelerator.
  • 4k/HDR
  • text subtitle/Closed Captions/image subtitle(dvbsub/dvdsub/pgssub)
  • Picture in Picture
  • Record video
  • De-interlace auto detect
  • Spatial Audio
  • 360° panorama video.

Requirements

  • iOS 13 +, macOS 10.15 +, tvOS 13 +, xrOS 1 +

Demo

cd Demo
pod install
  • Open Demo/Demo.xcworkspace with Xcode.

Quick Start

CocoaPods

Make sure to use the latest version cocoapods 1.10.1+, which can be installed using the command brew install cocoapods

target 'ProjectName' do
    use_frameworks!
    pod 'KSPlayer',:git => 'https://github.com/kingslay/KSPlayer.git', :branch => 'develop'
    pod 'FFmpegKit',:git => 'https://github.com/kingslay/FFmpegKit.git', :branch => 'main'
    pod 'OpenSSL',:git => 'https://github.com/kingslay/FFmpegKit.git', :branch => 'main'
end

Swift Package Manager

dependencies: [
    .package(url: "https://github.com/kingslay/KSPlayer.git", .branch("develop"))
]

Usage

initialize

KSOptions.secondPlayerType = KSMEPlayer.self
playerView = IOSVideoPlayerView()
view.addSubview(playerView)
playerView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    playerView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor),
    playerView.leftAnchor.constraint(equalTo: view.leftAnchor),
    playerView.rightAnchor.constraint(equalTo: view.rightAnchor),
    playerView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
playerView.backBlock = { [unowned self] in
    if UIApplication.shared.statusBarOrientation.isLandscape {
        self.playerView.updateUI(isLandscape: false)
    } else {
        self.navigationController?.popViewController(animated: true)
    }
}

Setting up a regular video

playerView.set(url:URL(string: "http://baobab.wdjcdn.com/14525705791193.mp4")!)
playerView.set(resource: KSPlayerResource(url: url, name: name!, cover: URL(string: "http://img.wdjimg.com/image/video/447f973848167ee5e44b67c8d4df9839_0_0.jpeg"), subtitleURL: URL(string: "http://example.ksplay.subtitle")))

Multi-definition, with cover video

let res0 = KSPlayerResourceDefinition(url: URL(string: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")!,
                                      definition: "高清")
let res1 = KSPlayerResourceDefinition(url: URL(string: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")!,
                                      definition: "标清")
   
let asset = KSPlayerResource(name: "Big Buck Bunny",
                             definitions: [res0, res1],
                             cover: URL(string: "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Big_buck_bunny_poster_big.jpg/848px-Big_buck_bunny_poster_big.jpg"))
playerView.set(resource: asset)

Setting up an HTTP header

let options = KSOptions()
options.appendHeader(["Referer":"https:www.xxx.com"])
let definition = KSPlayerResourceDefinition(url: URL(string: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")!,
                                            definition: "高清",
                                            options: options)
let asset = KSPlayerResource(name: "Video Name",
                             definitions: [definition])
playerView.set(resource: asset)

Listening status change

// Listen to play time change
playerView.playTimeDidChange = { (currentTime: TimeInterval, totalTime: TimeInterval) in
    print("playTimeDidChange currentTime: \(currentTime) totalTime: \(totalTime)")
}

// Delegates
public protocol PlayerControllerDelegate: class {
    func playerController(state: KSPlayerState)
    func playerController(currentTime: TimeInterval, totalTime: TimeInterval)
    func playerController(finish error: Error?)
    func playerController(maskShow: Bool)
    func playerController(action: PlayerButtonType)
    // `bufferedCount: 0` indicates first time loading
    func playerController(bufferedCount: Int, consumeTime: TimeInterval)
}

Advanced Usage

  • Inherits PlayerView's custom play logic and UI.

    class CustomVideoPlayerView: IOSVideoPlayerView {
        override func updateUI(isLandscape: Bool) {
            super.updateUI(isLandscape: isLandscape)
            toolBar.playbackRateButton.isHidden = true
        }
    
        override func onButtonPressed(type: PlayerButtonType, button: UIButton) {
            if type == .landscape {
                // Your own button press behaviour here
            } else {
                super.onButtonPressed(type: type, button: button)
            }
        }
    }
  • Selecting Tracks

       override open func player(layer: KSPlayerLayer, state: KSPlayerState) {
            super.player(layer: layer, state: state)
            if state == .readyToPlay, let player = layer.player {
                let tracks = player.tracks(mediaType: .audio)
                let track = tracks[1]
                /// the name of the track
                let name = track.name
                /// the language of the track
                let language = track.language
                /// selecting the one
                player.select(track: track)
            }
       }
  • Set the properties in KSOptions

    open class KSOptions {
      /// 最低缓存视频时间
      @Published
      public var preferredForwardBufferDuration = KSOptions.preferredForwardBufferDuration
      /// 最大缓存视频时间
      public var maxBufferDuration = KSOptions.maxBufferDuration
      /// 是否开启秒开
      public var isSecondOpen = KSOptions.isSecondOpen
      /// 开启精确seek
      public var isAccurateSeek = KSOptions.isAccurateSeek
      /// Applies to short videos only
      public var isLoopPlay = KSOptions.isLoopPlay
      /// 是否自动播放,默认false
      public var isAutoPlay = KSOptions.isAutoPlay
      /// seek完是否自动播放
      public var isSeekedAutoPlay = KSOptions.isSeekedAutoPlay
      /*
       AVSEEK_FLAG_BACKWARD: 1
       AVSEEK_FLAG_BYTE: 2
       AVSEEK_FLAG_ANY: 4
       AVSEEK_FLAG_FRAME: 8
       */
      public var seekFlags = Int32(0)
      // ffmpeg only cache http
      public var cache = false
      public var outputURL: URL?
      public var display = DisplayEnum.plane
      public var avOptions = [String: Any]()
      public var formatContextOptions = [String: Any]()
      public var decoderOptions = [String: Any]()
      public var probesize: Int64?
      public var maxAnalyzeDuration: Int64?
      public var lowres = UInt8(0)
      public var startPlayTime: TimeInterval = 0
      public var startPlayRate: Float = 1.0
      public var registerRemoteControll: Bool = true // 默认支持来自系统控制中心的控制
      public var referer: String?
      public var userAgent: String?
        // audio
      public var audioFilters = [String]()
      public var syncDecodeAudio = false
      // sutile
      public var autoSelectEmbedSubtitle = true
      public var subtitleDisable = false
      public var isSeekImageSubtitle = false
      // video
      public var videoDelay = 0.0 // s
      public var autoDeInterlace = false
      public var autoRotate = true
      public var destinationDynamicRange: DynamicRange?
      public var videoAdaptable = true
      public var videoFilters = [String]()
      public var syncDecodeVideo = false
      public var hardwareDecode = KSOptions.hardwareDecode
      public var asynchronousDecompression = true
      public var videoDisable = false
      public var canStartPictureInPictureAutomaticallyFromInline = true
    }

Effect

gif

Developments and Tests

Any contributing and pull requests are warmly welcome. However, before you plan to implement some features or try to fix an uncertain issue, it is recommended to open a discussion first. It would be appreciated if your pull requests could build and with all tests green. :)

Backers & Sponsors

Open-source projects cannot live long without your help. If you find KSPlayer to be useful, please consider supporting this project by becoming a sponsor.

Become a sponsor through GitHub Sponsors. ❤️

Your user icon or company logo shows up this with a link to your home page.

UnknownCoder807 skrew Kimentanm nakiostudio

Communication

1

ksplayer's People

Contributors

kingslay avatar weitieda avatar nicknull avatar birdmichael avatar matteogobbi avatar strangeliu avatar

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.