Code Monkey home page Code Monkey logo

videoplayer's Introduction

VideoPlayer

codebeat badge


Demo

Screenshot

  1. Clone or download the project.
  2. In the terminal, run swift package resolve.
  3. Open VideoPlayer.xcodeproj and run Demo target.

Features

  • Fully customizable UI.
  • Plays local media or streams remote media over HTTP.
  • Built-in caching mechanism to support playback while downloading.
  • Can preload multiple videos at any time.
  • Support seek to duration.
  • Simple API.

Quick Start

struct ContentView : View {
    @State private var play: Bool = true
    
    var body: some View {
        VideoPlayer(url: someVideoURL, play: $play)
    }
}

Advances

struct ContentView : View {  
    @State private var autoReplay: Bool = true 
    @State private var mute: Bool = false      
    @State private var play: Bool = true       
    @State private var time: CMTime = .zero  
    
    var body: some View {
        VideoPlayer(url: someVideoURL, play: $play, time: $time)
            .autoReplay(autoReplay)
            .mute(mute)
            .onBufferChanged { progress in
                // Network loading buffer progress changed
            }
            .onPlayToEndTime { 
                // Play to the end time.
            }
            .onReplay { 
                // Replay after playing to the end. 
            }
            .onStateChanged { state in 
                switch state {
                case .loading:
                    // Loading...
                case .playing(let totalDuration):
                    // Playing...
                case .paused(let playProgress, let bufferProgress):
                    // Paused...
                case .error(let error):
                    // Error...
                }
            }
    }
}

Preload

Set the video urls to be preload queue. Preloading will automatically cache a short segment of the beginning of the video and decide whether to start or pause the preload based on the buffering of the currently playing video.

VideoPlayer.preload(urls: [URL])

Set the preload size, the default value is 1024 * 1024, unit is byte.

VideoPlayer.preloadByteCount = 1024 * 1024 // = 1M

Cache

Get the total size of the video cache.

let size = VideoPlayer.calculateCachedSize()

Clean up all caches.

VideoPlayer.cleanAllCache()

Installation

Swift Package Manager

  1. Select Xcode -> File -> Swift Packages -> Add Package Dependency...
  2. Enter https://github.com/wxxsw/VideoPlayer.
  3. Click Next, then select the version, complete.

Requirements

  • iOS 13+
  • Xcode 11+
  • Swift 5+

Thanks

Banner Design by @aduqin

License

VideoPlayer is released under the MIT license. See LICENSE for details.

videoplayer's People

Contributors

conversun avatar graemeharrison avatar phongngo511 avatar wxxsw 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  avatar  avatar  avatar  avatar  avatar  avatar

videoplayer's Issues

Not effective index changing

I realized that when we press the next Video button, previous video still tries to complete the download. This situation puts great burden on network load as well as causing dramatic decrease in video download speed. Is there any quick fixes that you can suggest. Otherwise I can work on creating PR. Thank you in advance

Need a seekTo duration method

In need of a seekTo(duration) method so that we can externally control the progress of a video by integrating it with other elements of our own in the project Much appreciated ! 💯

Scale Video

Is there any way to scale video properly. My video looks stretched when using the player.

GSPlayer compilation error on Version 12.0 (12A7208)

Cant run VideoPlayer with iOS 14 using Version 12.0 (12A7208)
Method cannot be in an @objc extension of a class (without @nonobjc) because the type of the parameter 1 cannot be represented in Objective-C
on

    @discardableResult
    open func addBoundaryTimeObserver(forTimes times: [CMTime], queue: DispatchQueue? = nil, using: @escaping () -> Void) -> Any? {
        return player?.addBoundaryTimeObserver(forTimes: times.map { NSValue(time: $0) }, queue: queue, using: using)
    }

method in VideoPlayerView.swift

Crash app with log

[plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x6000024a2e20> F8BB1C28-BAE8-11D6-9C31-00039315CD46

Error when app is closed

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of AVPlayer cannot remove a time observer that was added by a different instance of AVPlayer.'

Cannot allocate memory crash

Hello, we are facing several issues in our Crashlytics, it looks like an issue with preloading the cache when there is not enough memory on the device, we support only devices with iOS 14+, full log:

Fatal Exception: NSFileHandleOperationException
0 CoreFoundation 0x19803186c __exceptionPreprocess
1 libobjc.A.dylib 0x1ad04ac50 objc_exception_throw
2 Foundation 0x1993227f4 -[NSConcreteFileHandle readDataUpToLength:error:]
3 Foundation 0x1992b791c +[NSPropertyListSerialization writePropertyList:toStream:format:options:error:]
4 0x10469e874 VideoDownloaderHandler.processActions()
5 0x10469c388 VideoDownloader.download(from:length:)
6 0x1046a5f70 VideoPreloadManager.start()
7 0x1046a6d98 specialized VideoPreloadManager.downloader(:didFinished:)
8 0x10469e824 VideoDownloaderHandler.processActions()
9 0x10469e914 VideoDownloaderHandler.processActions()
10 0x10469e914 VideoDownloaderHandler.processActions()
11 0x10469c388 VideoDownloader.download(from:length:)
12 0x1046a5f70 VideoPreloadManager.start()
13 0x1046a6d98 specialized VideoPreloadManager.downloader(
:didFinished:)
14 0x10469e824 VideoDownloaderHandler.processActions()
15 0x10469e914 VideoDownloaderHandler.processActions()
16 0x10469e914 VideoDownloaderHandler.processActions()
17 0x10469c388 VideoDownloader.download(from:length:)
18 0x1046a5f70 VideoPreloadManager.start()
19 0x1046a6d98 specialized VideoPreloadManager.downloader(:didFinished:)
20 0x10469e824 VideoDownloaderHandler.processActions()
21 0x10469e914 VideoDownloaderHandler.processActions()
22 0x10469e914 VideoDownloaderHandler.processActions()
23 0x10469c388 VideoDownloader.download(from:length:)
24 0x1046a5f70 VideoPreloadManager.start()
25 0x1046a6d98 specialized VideoPreloadManager.downloader(
:didFinished:)
26 0x10469e824 VideoDownloaderHandler.processActions()
27 0x10469e914 VideoDownloaderHandler.processActions()
28 0x10469e914 VideoDownloaderHandler.processActions()
29 0x10469c388 VideoDownloader.download(from:length:)
30 0x1046a5f70 VideoPreloadManager.start()
31 0x1046a6d98 specialized VideoPreloadManager.downloader(:didFinished:)
32 0x10469e824 VideoDownloaderHandler.processActions()
33 0x10469e914 VideoDownloaderHandler.processActions()
34 0x10469e914 VideoDownloaderHandler.processActions()
35 0x10469c388 VideoDownloader.download(from:length:)
36 0x1046a5f70 VideoPreloadManager.start()
37 0x1046a6d98 specialized VideoPreloadManager.downloader(
:didFinished:)
38 0x10469e824 VideoDownloaderHandler.processActions()
39 0x10469e914 VideoDownloaderHandler.processActions()
40 0x10469e914 VideoDownloaderHandler.processActions()
41 0x10469c388 VideoDownloader.download(from:length:)
42 0x1046a5f70 VideoPreloadManager.start()
43 0x1046a6d98 specialized VideoPreloadManager.downloader(:didFinished:)
44 0x10469e824 VideoDownloaderHandler.processActions()
45 0x10469e914 VideoDownloaderHandler.processActions()
46 0x10469e914 VideoDownloaderHandler.processActions()
47 0x10469c388 VideoDownloader.download(from:length:)
48 0x1046a5f70 VideoPreloadManager.start()
49 0x1046a6d98 specialized VideoPreloadManager.downloader(
:didFinished:)
50 0x10469e824 VideoDownloaderHandler.processActions()
51 0x10469e914 VideoDownloaderHandler.processActions()
52 0x10469e914 VideoDownloaderHandler.processActions()
53 0x10469c388 VideoDownloader.download(from:length:)
54 0x1046a5f70 VideoPreloadManager.start()
55 0x1046a6d98 specialized VideoPreloadManager.downloader(:didFinished:)
56 0x10469e824 VideoDownloaderHandler.processActions()
57 0x10469e914 VideoDownloaderHandler.processActions()
58 0x10469e914 VideoDownloaderHandler.processActions()
59 0x10469c388 VideoDownloader.download(from:length:)
60 0x1046a5f70 VideoPreloadManager.start()
61 0x1046a6d98 specialized VideoPreloadManager.downloader(
:didFinished:)
62 0x10469e824 VideoDownloaderHandler.processActions()
63 0x10469e914 VideoDownloaderHandler.processActions()
64 0x10469e914 VideoDownloaderHandler.processActions()
65 0x10469c388 VideoDownloader.download(from:length:)
66 F 0x1046a5f70 VideoPreloadManager.start()
67 0x1046a6d98 specialized VideoPreloadManager.downloader(_:didFinished:)
68 0x10469e824 VideoDownloaderHandler.processActions()
69 0x10469e914 VideoDownloaderHandler.processActions()
70 0x10469e914 VideoDownloaderHandler.processActions()
71 0x10469c388 VideoDownloader.download(from:length:)
72 0x1046a5f70 VideoPreloadManager.start()
73 0x1046a5c1c VideoPreloadManager.set(waiting:)
74 0x104691d94 static VideoPlayer.preload(urls:)

I want isMute to be a binding bool

I want isMute to be a binding bool . In Instagram when we tap on a video mute toggles so for a similar behaviour it's better to have isMute to toggle

Support UIKIT

I love your library so much and I wish if it supports the UIKIT or if there is a pod for it

next video

when click on next video cause VideoPlayer flicker. Can we disable that flicker?

Can't start video from specific time

Hi!
When i'm trying to start the video from specific time, i.e. give the time state a different value other then .zero, the video still starts from the beginning. It seems that the startObserver function make it. Is there a way to do it? Thanks!

Any action causes video to restart

When tapping any button that updates state, including even opening a sheet, the player will restart the playing video.
How can I make it so that it allows the video to continue playing? Even muting restarts the video.

struct CustomVideoPlayer: View {
    let url: String
    @State private var shouldPlay: Bool = true
    @State private var autoReplay: Bool = true
    @State private var mute: Bool = false
    @State private var time: CMTime = .zero
    
    var body: some View {
        VideoPlayer(url: URL(string: url)!, play: $shouldPlay)
            .autoReplay(autoReplay)
            .mute(mute)
            .contentMode(.scaleAspectFit)

        
    }
}

crash when load next video

Crash will not present if stop video playing before switching next video. But I want auto play when swipe to new video, just like tiktok.

crash log:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of AVPlayer cannot remove a time observer that was added by a different instance of AVPlayer.'

source code:
`struct ContentView: View {
@State private var index = 0
@State private var play: Bool = true
var manager: Manager { return Manager.shared }
var count: Int { return manager.datas.count }
var data: MyData { return manager.datas[index] }
var url: URL? { return URL(string: data.url) }

var body: some View {
    ZStack {
        Rectangle().fill().foregroundColor(.black)
        url.map { VideoPlayer(url: $0, play: $play) }
    }
    .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .local)
                .onEnded({ value in
                    if value.translation.height < 0, index < count - 1 {
                        index += 1
                    }
                    if value.translation.height > 0, index > 0 {
                        index -= 1
                    }
                }))
    .ignoresSafeArea()
}

}`

Quick start not playing

*Used swift package to create dependency

*included the following:
import AVFoundation
import SwiftUI
import VideoPlayer
import UIKit

added to plist:
App Transport Security Settings
-- Allow Arbitrary Loads
-- Allow Arbitrary Loads for Media
-- AllowArbitrary Loads for Web Content

However, it is still not playing. Please help

Buffering and sound problem

hello, videos from url dont play the sound.
Also on slow internet connections, the player buffers alot, how can i set the player to only play when a certain amount of data is predownloaded and pause if the current data is insufficient (specify buffer size)

Header Range issue

Sometimes server returns error 416. I suppose this happens because of wrong range header if preload byte count more then file size. Header when error occurs is Range = "bytes=170636-2097151". First index is more then file size too. When header is "bytes=0-2097151" server returns 0 - 170635 with 206 code after that framework make request with out of bounds range "bytes=170636-2097151" but I think it should be "bytes=170635-170636"

Preconditions: server Amazon CDN, file size = 170636, preloadByteCount = 2097152

AVFoundation issues - Can't play URLs from firebase

Hi! I am having an issue trying to play a video that I get from Firebase.

Error:
Error Domain=AVFoundationErrorDomain Code=-11828 "Cannot Open" UserInfo={NSLocalizedFailureReason=This media format is not supported., NSLocalizedDescription=Cannot Open, NSUnderlyingError=0x600003f987b0 {Error Domain=NSOSStatusErrorDomain Code=-12847 "(null)"}}

According to apple, Code= -11828 is The system can’t open the file because it’s in an unrecognized format.
I couldn't find what Code=-12847 is.

These video urls don't come with the extension of the file, like .mov or .mp4. I tried to apply it manually without success.
They work on browser and they work when I try to use AVPlayer.

Any idea of what might be going wrong?
I really want to use this library as it's very complete and well done :)

I'm sorry I can't give you any links, but I can give you any other information that could help.
Thanks!

Multiple Video In a List is Causing an Issue

I am using VideoPlayer in List, but the issue I am facing is that first One or Two videos playing correctly, but after I scrolling List View the remaining video did not play properly.
Please Help me for that. Thanks in Advance.

The framework is broken

If you reset package caches or use the framework for the fist time you will get this error:

Screenshot 2023-08-14 at 4 37 35 PM

Possibly caused because there is no tag for last updates of GSPlayer

full screen video

how to make a video full screen?
currently, it resizes based on video size

This Media Format is Not Supported (.mov file)

@wxxsw Hi there - I'm getting this error:
Error Error Domain=AVFoundationErrorDomain Code=-11828 "Cannot Open" UserInfo={NSLocalizedFailureReason=This media format is not supported., NSLocalizedDescription=Cannot Open, NSUnderlyingError=0x281bd39c0 {Error Domain=NSOSStatusErrorDomain Code=-12847 "(null)"}}

trying to play a file like this: https://f000.backblazeb2.com/file/lighthouseStories/641FoyZcKFbHiD1Ceks4-snippet

This file URL works just fine with the standard AVPlayer, not sure why I'm getting this error. Please advise.

Cocoa is not available when building for iOS.

Cocoa is not available when building for iOS. Consider using #if !os(iOS) to conditionally import this framework.

when I want to build my app I got this error in GSAVPlayerViewController class.

it was ok on 1.1.6 but after updating to the latest version got this error.
my Xcode version: 12.2

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.