Repository files navigation

GSPlayer

Features

  • Fully customizable UI.
  • Easy to use API and callbacks.
  • Built-in caching mechanism to support playback while downloading (mp4).
  • Can preload multiple videos at any time.
  • Can be embedded into UITableView and UICollectionView.
  • Provide full screen transition.
  • Complete Demo.

Quick Start

  1. Add VideoPlayerView to the interface.
letplayerView=VideoPlayerView()
view.addSubview(playerView)
// Or in IB, specify the type of custom View as VideoPlayerView.
  1. Play Video.
playerView.play(for: someURL)
  1. Pause/Resume Video.
if playerView.state ==.playing {
playerView.pause(reason:.userInteraction)}else{
playerView.resume()}
  1. Update control UI based on playback status.
playerView.stateDidChanged ={ state inswitch state {case.none:print("none")case.error(let error):print("error - \(error.localizedDescription)")case.loading:print("loading")case.paused(let playing,let buffering):print("paused - progress \(Int(playing *100))% buffering \(Int(buffering *100))%")case.playing:print("playing")}}

Documents

Cache

Get the total size of the video cache.

VideoCacheManager.calculateCachedSize()

Clean up all caches.

VideoCacheManager.cleanAllCache()

Preload

Set the video URL to be preloaded. 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.

VideoPreloadManager.shared.set(waiting:[URL])

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

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

Fullscreen

See demo.

PlayerView

Property

An object that manages a player's visual output.

publicletplayerLayer:AVPlayerLayer{get}

Get current video status.

publicenumState{
/// None
case none
/// From the first load to get the first frame of the video
case loading
/// Playing now
case playing
/// Pause, will be called repeatedly when the buffer progress changes
case paused(playing:Double, buffering:Double)
/// An error occurred and cannot continue playing
case error(NSError)}publicvarstate:State{get}

The reason the video was paused.

publicenumPausedReason{
/// Pause because the player is not visible, stateDidChanged is not called when the buffer progress changes
case hidden
/// Pause triggered by user interaction, default behavior
case userInteraction
/// Waiting for resource completion buffering
case waitingKeepUp
}publicvarpausedReason:PausedReason{get}

Number of replays.

publicvarreplayCount:Int{get}

Played progress, value range 0-1.

publicvarplaying:Double{get}

Played length in seconds.

publicvarcurrentDuration:Double{get}

Buffered progress, value range 0-1.

publicvarbuffering:Double{get}

Buffered length in seconds.

publicvarcurrentBufferDuration:Double{get}

Total video duration in seconds.

publicvartotalDuration:Double{get}

The total watch time of this video, in seconds.

publicvarwatchDuration:Double{get}

Whether the video is muted, only for this instance.

publicvarisMuted:Bool{getset}

Video volume, only for this instance.

publicvarvolume:Double{getset}

Callback

Playback status changes, such as from play to pause.

publicvarstateDidChanged:((State)->Void)?

Replay after playing to the end.

publicvarreplay:(()->Void)?

Method

Play a video of the specified url.

func play(for url:URL)

Pause video.

func pause(reason:PausedReason)

Continue playing video.

func resume()

Installation

GSPlayer is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod'GSPlayer'

Contribution

Issue

If you find a bug or need a help, you can create a issue

Pull Request

We are happy to accept pull requests :D. But please make sure it's needed by most developers and make it simple to use. If you are not sure, create an issue and we can discuss it before you get to coding.

License

The MIT License (MIT)

About

⏯ Video player, support for caching, preload, fullscreen transition and custom control view. 视频播放器,支持边下边播、预加载、全屏转场和自定义控制层

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

GSPlayer

Features

  • Fully customizable UI.
  • Easy to use API and callbacks.
  • Built-in caching mechanism to support playback while downloading (mp4).
  • Can preload multiple videos at any time.
  • Can be embedded into UITableView and UICollectionView.
  • Provide full screen transition.
  • Complete Demo.

Quick Start

  1. Add VideoPlayerView to the interface.
letplayerView=VideoPlayerView()
view.addSubview(playerView)
// Or in IB, specify the type of custom View as VideoPlayerView.
  1. Play Video.
playerView.play(for: someURL)
  1. Pause/Resume Video.
if playerView.state ==.playing {
playerView.pause(reason:.userInteraction)}else{
playerView.resume()}
  1. Update control UI based on playback status.
playerView.stateDidChanged ={ state inswitch state {case.none:print("none")case.error(let error):print("error - \(error.localizedDescription)")case.loading:print("loading")case.paused(let playing,let buffering):print("paused - progress \(Int(playing *100))% buffering \(Int(buffering *100))%")case.playing:print("playing")}}

Documents

Cache

Get the total size of the video cache.

VideoCacheManager.calculateCachedSize()

Clean up all caches.

VideoCacheManager.cleanAllCache()

Preload

Set the video URL to be preloaded. 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.

VideoPreloadManager.shared.set(waiting:[URL])

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

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

Fullscreen

See demo.

PlayerView

Property

An object that manages a player's visual output.

publicletplayerLayer:AVPlayerLayer{get}

Get current video status.

publicenumState{
/// None
case none
/// From the first load to get the first frame of the video
case loading
/// Playing now
case playing
/// Pause, will be called repeatedly when the buffer progress changes
case paused(playing:Double, buffering:Double)
/// An error occurred and cannot continue playing
case error(NSError)}publicvarstate:State{get}

The reason the video was paused.

publicenumPausedReason{
/// Pause because the player is not visible, stateDidChanged is not called when the buffer progress changes
case hidden
/// Pause triggered by user interaction, default behavior
case userInteraction
/// Waiting for resource completion buffering
case waitingKeepUp
}publicvarpausedReason:PausedReason{get}

Number of replays.

publicvarreplayCount:Int{get}

Played progress, value range 0-1.

publicvarplaying:Double{get}

Played length in seconds.

publicvarcurrentDuration:Double{get}

Buffered progress, value range 0-1.

publicvarbuffering:Double{get}

Buffered length in seconds.

publicvarcurrentBufferDuration:Double{get}

Total video duration in seconds.

publicvartotalDuration:Double{get}

The total watch time of this video, in seconds.

publicvarwatchDuration:Double{get}

Whether the video is muted, only for this instance.

publicvarisMuted:Bool{getset}

Video volume, only for this instance.

publicvarvolume:Double{getset}

Callback

Playback status changes, such as from play to pause.

publicvarstateDidChanged:((State)->Void)?

Replay after playing to the end.

publicvarreplay:(()->Void)?

Method

Play a video of the specified url.

func play(for url:URL)

Pause video.

func pause(reason:PausedReason)

Continue playing video.

func resume()

Installation

GSPlayer is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod'GSPlayer'

Contribution

Issue

If you find a bug or need a help, you can create a issue

Pull Request

We are happy to accept pull requests :D. But please make sure it's needed by most developers and make it simple to use. If you are not sure, create an issue and we can discuss it before you get to coding.

License

The MIT License (MIT)

About

⏯ Video player, support for caching, preload, fullscreen transition and custom control view. 视频播放器,支持边下边播、预加载、全屏转场和自定义控制层

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

GSPlayer

Features

  • Fully customizable UI.
  • Easy to use API and callbacks.
  • Built-in caching mechanism to support playback while downloading (mp4).
  • Can preload multiple videos at any time.
  • Can be embedded into UITableView and UICollectionView.
  • Provide full screen transition.
  • Complete Demo.

Quick Start

  1. Add VideoPlayerView to the interface.
letplayerView=VideoPlayerView()
view.addSubview(playerView)
// Or in IB, specify the type of custom View as VideoPlayerView.
  1. Play Video.
playerView.play(for: someURL)
  1. Pause/Resume Video.
if playerView.state ==.playing {
playerView.pause(reason:.userInteraction)}else{
playerView.resume()}
  1. Update control UI based on playback status.
playerView.stateDidChanged ={ state inswitch state {case.none:print("none")case.error(let error):print("error - \(error.localizedDescription)")case.loading:print("loading")case.paused(let playing,let buffering):print("paused - progress \(Int(playing *100))% buffering \(Int(buffering *100))%")case.playing:print("playing")}}

Documents

Cache

Get the total size of the video cache.

VideoCacheManager.calculateCachedSize()

Clean up all caches.

VideoCacheManager.cleanAllCache()

Preload

Set the video URL to be preloaded. 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.

VideoPreloadManager.shared.set(waiting:[URL])

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

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

Fullscreen

See demo.

PlayerView

Property

An object that manages a player's visual output.

publicletplayerLayer:AVPlayerLayer{get}

Get current video status.

publicenumState{
/// None
case none
/// From the first load to get the first frame of the video
case loading
/// Playing now
case playing
/// Pause, will be called repeatedly when the buffer progress changes
case paused(playing:Double, buffering:Double)
/// An error occurred and cannot continue playing
case error(NSError)}publicvarstate:State{get}

The reason the video was paused.

publicenumPausedReason{
/// Pause because the player is not visible, stateDidChanged is not called when the buffer progress changes
case hidden
/// Pause triggered by user interaction, default behavior
case userInteraction
/// Waiting for resource completion buffering
case waitingKeepUp
}publicvarpausedReason:PausedReason{get}

Number of replays.

publicvarreplayCount:Int{get}

Played progress, value range 0-1.

publicvarplaying:Double{get}

Played length in seconds.

publicvarcurrentDuration:Double{get}

Buffered progress, value range 0-1.

publicvarbuffering:Double{get}

Buffered length in seconds.

publicvarcurrentBufferDuration:Double{get}

Total video duration in seconds.

publicvartotalDuration:Double{get}

The total watch time of this video, in seconds.

publicvarwatchDuration:Double{get}

Whether the video is muted, only for this instance.

publicvarisMuted:Bool{getset}

Video volume, only for this instance.

publicvarvolume:Double{getset}

Callback

Playback status changes, such as from play to pause.

publicvarstateDidChanged:((State)->Void)?

Replay after playing to the end.

publicvarreplay:(()->Void)?

Method

Play a video of the specified url.

func play(for url:URL)

Pause video.

func pause(reason:PausedReason)

Continue playing video.

func resume()

Installation

GSPlayer is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod'GSPlayer'

Contribution

Issue

If you find a bug or need a help, you can create a issue

Pull Request

We are happy to accept pull requests :D. But please make sure it's needed by most developers and make it simple to use. If you are not sure, create an issue and we can discuss it before you get to coding.

License

The MIT License (MIT)

About

⏯ Video player, support for caching, preload, fullscreen transition and custom control view. 视频播放器,支持边下边播、预加载、全屏转场和自定义控制层

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

GSPlayer

Features

  • Fully customizable UI.
  • Easy to use API and callbacks.
  • Built-in caching mechanism to support playback while downloading (mp4).
  • Can preload multiple videos at any time.
  • Can be embedded into UITableView and UICollectionView.
  • Provide full screen transition.
  • Complete Demo.

Quick Start

  1. Add VideoPlayerView to the interface.
letplayerView=VideoPlayerView()
view.addSubview(playerView)
// Or in IB, specify the type of custom View as VideoPlayerView.
  1. Play Video.
playerView.play(for: someURL)
  1. Pause/Resume Video.
if playerView.state ==.playing {
playerView.pause(reason:.userInteraction)}else{
playerView.resume()}
  1. Update control UI based on playback status.
playerView.stateDidChanged ={ state inswitch state {case.none:print("none")case.error(let error):print("error - \(error.localizedDescription)")case.loading:print("loading")case.paused(let playing,let buffering):print("paused - progress \(Int(playing *100))% buffering \(Int(buffering *100))%")case.playing:print("playing")}}

Documents

Cache

Get the total size of the video cache.

VideoCacheManager.calculateCachedSize()

Clean up all caches.

VideoCacheManager.cleanAllCache()

Preload

Set the video URL to be preloaded. 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.

VideoPreloadManager.shared.set(waiting:[URL])

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

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

Fullscreen

See demo.

PlayerView

Property

An object that manages a player's visual output.

publicletplayerLayer:AVPlayerLayer{get}

Get current video status.

publicenumState{
/// None
case none
/// From the first load to get the first frame of the video
case loading
/// Playing now
case playing
/// Pause, will be called repeatedly when the buffer progress changes
case paused(playing:Double, buffering:Double)
/// An error occurred and cannot continue playing
case error(NSError)}publicvarstate:State{get}

The reason the video was paused.

publicenumPausedReason{
/// Pause because the player is not visible, stateDidChanged is not called when the buffer progress changes
case hidden
/// Pause triggered by user interaction, default behavior
case userInteraction
/// Waiting for resource completion buffering
case waitingKeepUp
}publicvarpausedReason:PausedReason{get}

Number of replays.

publicvarreplayCount:Int{get}

Played progress, value range 0-1.

publicvarplaying:Double{get}

Played length in seconds.

publicvarcurrentDuration:Double{get}

Buffered progress, value range 0-1.

publicvarbuffering:Double{get}

Buffered length in seconds.

publicvarcurrentBufferDuration:Double{get}

Total video duration in seconds.

publicvartotalDuration:Double{get}

The total watch time of this video, in seconds.

publicvarwatchDuration:Double{get}

Whether the video is muted, only for this instance.

publicvarisMuted:Bool{getset}

Video volume, only for this instance.

publicvarvolume:Double{getset}

Callback

Playback status changes, such as from play to pause.

publicvarstateDidChanged:((State)->Void)?

Replay after playing to the end.

publicvarreplay:(()->Void)?

Method

Play a video of the specified url.

func play(for url:URL)

Pause video.

func pause(reason:PausedReason)

Continue playing video.

func resume()

Installation

GSPlayer is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod'GSPlayer'

Contribution

Issue

If you find a bug or need a help, you can create a issue

Pull Request

We are happy to accept pull requests :D. But please make sure it's needed by most developers and make it simple to use. If you are not sure, create an issue and we can discuss it before you get to coding.

License

The MIT License (MIT)

About

⏯ Video player, support for caching, preload, fullscreen transition and custom control view. 视频播放器,支持边下边播、预加载、全屏转场和自定义控制层

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

GSPlayer

Features

  • Fully customizable UI.
  • Easy to use API and callbacks.
  • Built-in caching mechanism to support playback while downloading (mp4).
  • Can preload multiple videos at any time.
  • Can be embedded into UITableView and UICollectionView.
  • Provide full screen transition.
  • Complete Demo.

Quick Start

  1. Add VideoPlayerView to the interface.
letplayerView=VideoPlayerView()
view.addSubview(playerView)
// Or in IB, specify the type of custom View as VideoPlayerView.
  1. Play Video.
playerView.play(for: someURL)
  1. Pause/Resume Video.
if playerView.state ==.playing {
playerView.pause(reason:.userInteraction)}else{
playerView.resume()}
  1. Update control UI based on playback status.
playerView.stateDidChanged ={ state inswitch state {case.none:print("none")case.error(let error):print("error - \(error.localizedDescription)")case.loading:print("loading")case.paused(let playing,let buffering):print("paused - progress \(Int(playing *100))% buffering \(Int(buffering *100))%")case.playing:print("playing")}}

Documents

Cache

Get the total size of the video cache.

VideoCacheManager.calculateCachedSize()

Clean up all caches.

VideoCacheManager.cleanAllCache()

Preload

Set the video URL to be preloaded. 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.

VideoPreloadManager.shared.set(waiting:[URL])

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

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

Fullscreen

See demo.

PlayerView

Property

An object that manages a player's visual output.

publicletplayerLayer:AVPlayerLayer{get}

Get current video status.

publicenumState{
/// None
case none
/// From the first load to get the first frame of the video
case loading
/// Playing now
case playing
/// Pause, will be called repeatedly when the buffer progress changes
case paused(playing:Double, buffering:Double)
/// An error occurred and cannot continue playing
case error(NSError)}publicvarstate:State{get}

The reason the video was paused.

publicenumPausedReason{
/// Pause because the player is not visible, stateDidChanged is not called when the buffer progress changes
case hidden
/// Pause triggered by user interaction, default behavior
case userInteraction
/// Waiting for resource completion buffering
case waitingKeepUp
}publicvarpausedReason:PausedReason{get}

Number of replays.

publicvarreplayCount:Int{get}

Played progress, value range 0-1.

publicvarplaying:Double{get}

Played length in seconds.

publicvarcurrentDuration:Double{get}

Buffered progress, value range 0-1.

publicvarbuffering:Double{get}

Buffered length in seconds.

publicvarcurrentBufferDuration:Double{get}

Total video duration in seconds.

publicvartotalDuration:Double{get}

The total watch time of this video, in seconds.

publicvarwatchDuration:Double{get}

Whether the video is muted, only for this instance.

publicvarisMuted:Bool{getset}

Video volume, only for this instance.

publicvarvolume:Double{getset}

Callback

Playback status changes, such as from play to pause.

publicvarstateDidChanged:((State)->Void)?

Replay after playing to the end.

publicvarreplay:(()->Void)?

Method

Play a video of the specified url.

func play(for url:URL)

Pause video.

func pause(reason:PausedReason)

Continue playing video.

func resume()

Installation

GSPlayer is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod'GSPlayer'

Contribution

Issue

If you find a bug or need a help, you can create a issue

Pull Request

We are happy to accept pull requests :D. But please make sure it's needed by most developers and make it simple to use. If you are not sure, create an issue and we can discuss it before you get to coding.

License

The MIT License (MIT)

About

⏯ Video player, support for caching, preload, fullscreen transition and custom control view. 视频播放器,支持边下边播、预加载、全屏转场和自定义控制层

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

GSPlayer

Features

  • Fully customizable UI.
  • Easy to use API and callbacks.
  • Built-in caching mechanism to support playback while downloading (mp4).
  • Can preload multiple videos at any time.
  • Can be embedded into UITableView and UICollectionView.
  • Provide full screen transition.
  • Complete Demo.

Quick Start

  1. Add VideoPlayerView to the interface.
letplayerView=VideoPlayerView()
view.addSubview(playerView)
// Or in IB, specify the type of custom View as VideoPlayerView.
  1. Play Video.
playerView.play(for: someURL)
  1. Pause/Resume Video.
if playerView.state ==.playing {
playerView.pause(reason:.userInteraction)}else{
playerView.resume()}
  1. Update control UI based on playback status.
playerView.stateDidChanged ={ state inswitch state {case.none:print("none")case.error(let error):print("error - \(error.localizedDescription)")case.loading:print("loading")case.paused(let playing,let buffering):print("paused - progress \(Int(playing *100))% buffering \(Int(buffering *100))%")case.playing:print("playing")}}

Documents

Cache

Get the total size of the video cache.

VideoCacheManager.calculateCachedSize()

Clean up all caches.

VideoCacheManager.cleanAllCache()

Preload

Set the video URL to be preloaded. 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.

VideoPreloadManager.shared.set(waiting:[URL])

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

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

Fullscreen

See demo.

PlayerView

Property

An object that manages a player's visual output.

publicletplayerLayer:AVPlayerLayer{get}

Get current video status.

publicenumState{
/// None
case none
/// From the first load to get the first frame of the video
case loading
/// Playing now
case playing
/// Pause, will be called repeatedly when the buffer progress changes
case paused(playing:Double, buffering:Double)
/// An error occurred and cannot continue playing
case error(NSError)}publicvarstate:State{get}

The reason the video was paused.

publicenumPausedReason{
/// Pause because the player is not visible, stateDidChanged is not called when the buffer progress changes
case hidden
/// Pause triggered by user interaction, default behavior
case userInteraction
/// Waiting for resource completion buffering
case waitingKeepUp
}publicvarpausedReason:PausedReason{get}

Number of replays.

publicvarreplayCount:Int{get}

Played progress, value range 0-1.

publicvarplaying:Double{get}

Played length in seconds.

publicvarcurrentDuration:Double{get}

Buffered progress, value range 0-1.

publicvarbuffering:Double{get}

Buffered length in seconds.

publicvarcurrentBufferDuration:Double{get}

Total video duration in seconds.

publicvartotalDuration:Double{get}

The total watch time of this video, in seconds.

publicvarwatchDuration:Double{get}

Whether the video is muted, only for this instance.

publicvarisMuted:Bool{getset}

Video volume, only for this instance.

publicvarvolume:Double{getset}

Callback

Playback status changes, such as from play to pause.

publicvarstateDidChanged:((State)->Void)?

Replay after playing to the end.

publicvarreplay:(()->Void)?

Method

Play a video of the specified url.

func play(for url:URL)

Pause video.

func pause(reason:PausedReason)

Continue playing video.

func resume()

Installation

GSPlayer is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod'GSPlayer'

Contribution

Issue

If you find a bug or need a help, you can create a issue

Pull Request

We are happy to accept pull requests :D. But please make sure it's needed by most developers and make it simple to use. If you are not sure, create an issue and we can discuss it before you get to coding.

License

The MIT License (MIT)

About

⏯ Video player, support for caching, preload, fullscreen transition and custom control view. 视频播放器,支持边下边播、预加载、全屏转场和自定义控制层

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

GSPlayer

Features

  • Fully customizable UI.
  • Easy to use API and callbacks.
  • Built-in caching mechanism to support playback while downloading (mp4).
  • Can preload multiple videos at any time.
  • Can be embedded into UITableView and UICollectionView.
  • Provide full screen transition.
  • Complete Demo.

Quick Start

  1. Add VideoPlayerView to the interface.
letplayerView=VideoPlayerView()
view.addSubview(playerView)
// Or in IB, specify the type of custom View as VideoPlayerView.
  1. Play Video.
playerView.play(for: someURL)
  1. Pause/Resume Video.
if playerView.state ==.playing {
playerView.pause(reason:.userInteraction)}else{
playerView.resume()}
  1. Update control UI based on playback status.
playerView.stateDidChanged ={ state inswitch state {case.none:print("none")case.error(let error):print("error - \(error.localizedDescription)")case.loading:print("loading")case.paused(let playing,let buffering):print("paused - progress \(Int(playing *100))% buffering \(Int(buffering *100))%")case.playing:print("playing")}}

Documents

Cache

Get the total size of the video cache.

VideoCacheManager.calculateCachedSize()

Clean up all caches.

VideoCacheManager.cleanAllCache()

Preload

Set the video URL to be preloaded. 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.

VideoPreloadManager.shared.set(waiting:[URL])

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

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

Fullscreen

See demo.

PlayerView

Property

An object that manages a player's visual output.

publicletplayerLayer:AVPlayerLayer{get}

Get current video status.

publicenumState{
/// None
case none
/// From the first load to get the first frame of the video
case loading
/// Playing now
case playing
/// Pause, will be called repeatedly when the buffer progress changes
case paused(playing:Double, buffering:Double)
/// An error occurred and cannot continue playing
case error(NSError)}publicvarstate:State{get}

The reason the video was paused.

publicenumPausedReason{
/// Pause because the player is not visible, stateDidChanged is not called when the buffer progress changes
case hidden
/// Pause triggered by user interaction, default behavior
case userInteraction
/// Waiting for resource completion buffering
case waitingKeepUp
}publicvarpausedReason:PausedReason{get}

Number of replays.

publicvarreplayCount:Int{get}

Played progress, value range 0-1.

publicvarplaying:Double{get}

Played length in seconds.

publicvarcurrentDuration:Double{get}

Buffered progress, value range 0-1.

publicvarbuffering:Double{get}

Buffered length in seconds.

publicvarcurrentBufferDuration:Double{get}

Total video duration in seconds.

publicvartotalDuration:Double{get}

The total watch time of this video, in seconds.

publicvarwatchDuration:Double{get}

Whether the video is muted, only for this instance.

publicvarisMuted:Bool{getset}

Video volume, only for this instance.

publicvarvolume:Double{getset}

Callback

Playback status changes, such as from play to pause.

publicvarstateDidChanged:((State)->Void)?

Replay after playing to the end.

publicvarreplay:(()->Void)?

Method

Play a video of the specified url.

func play(for url:URL)

Pause video.

func pause(reason:PausedReason)

Continue playing video.

func resume()

Installation

GSPlayer is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod'GSPlayer'

Contribution

Issue

If you find a bug or need a help, you can create a issue

Pull Request

We are happy to accept pull requests :D. But please make sure it's needed by most developers and make it simple to use. If you are not sure, create an issue and we can discuss it before you get to coding.

License

The MIT License (MIT)

About

⏯ Video player, support for caching, preload, fullscreen transition and custom control view. 视频播放器,支持边下边播、预加载、全屏转场和自定义控制层

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

GSPlayer

Features

  • Fully customizable UI.
  • Easy to use API and callbacks.
  • Built-in caching mechanism to support playback while downloading (mp4).
  • Can preload multiple videos at any time.
  • Can be embedded into UITableView and UICollectionView.
  • Provide full screen transition.
  • Complete Demo.

Quick Start

  1. Add VideoPlayerView to the interface.
letplayerView=VideoPlayerView()
view.addSubview(playerView)
// Or in IB, specify the type of custom View as VideoPlayerView.
  1. Play Video.
playerView.play(for: someURL)
  1. Pause/Resume Video.
if playerView.state ==.playing {
playerView.pause(reason:.userInteraction)}else{
playerView.resume()}
  1. Update control UI based on playback status.
playerView.stateDidChanged ={ state inswitch state {case.none:print("none")case.error(let error):print("error - \(error.localizedDescription)")case.loading:print("loading")case.paused(let playing,let buffering):print("paused - progress \(Int(playing *100))% buffering \(Int(buffering *100))%")case.playing:print("playing")}}

Documents

Cache

Get the total size of the video cache.

VideoCacheManager.calculateCachedSize()

Clean up all caches.

VideoCacheManager.cleanAllCache()

Preload

Set the video URL to be preloaded. 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.

VideoPreloadManager.shared.set(waiting:[URL])

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

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

Fullscreen

See demo.

PlayerView

Property

An object that manages a player's visual output.

publicletplayerLayer:AVPlayerLayer{get}

Get current video status.

publicenumState{
/// None
case none
/// From the first load to get the first frame of the video
case loading
/// Playing now
case playing
/// Pause, will be called repeatedly when the buffer progress changes
case paused(playing:Double, buffering:Double)
/// An error occurred and cannot continue playing
case error(NSError)}publicvarstate:State{get}

The reason the video was paused.

publicenumPausedReason{
/// Pause because the player is not visible, stateDidChanged is not called when the buffer progress changes
case hidden
/// Pause triggered by user interaction, default behavior
case userInteraction
/// Waiting for resource completion buffering
case waitingKeepUp
}publicvarpausedReason:PausedReason{get}

Number of replays.

publicvarreplayCount:Int{get}

Played progress, value range 0-1.

publicvarplaying:Double{get}

Played length in seconds.

publicvarcurrentDuration:Double{get}

Buffered progress, value range 0-1.

publicvarbuffering:Double{get}

Buffered length in seconds.

publicvarcurrentBufferDuration:Double{get}

Total video duration in seconds.

publicvartotalDuration:Double{get}

The total watch time of this video, in seconds.

publicvarwatchDuration:Double{get}

Whether the video is muted, only for this instance.

publicvarisMuted:Bool{getset}

Video volume, only for this instance.

publicvarvolume:Double{getset}

Callback

Playback status changes, such as from play to pause.

publicvarstateDidChanged:((State)->Void)?

Replay after playing to the end.

publicvarreplay:(()->Void)?

Method

Play a video of the specified url.

func play(for url:URL)

Pause video.

func pause(reason:PausedReason)

Continue playing video.

func resume()

Installation

GSPlayer is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod'GSPlayer'

Contribution

Issue

If you find a bug or need a help, you can create a issue

Pull Request

We are happy to accept pull requests :D. But please make sure it's needed by most developers and make it simple to use. If you are not sure, create an issue and we can discuss it before you get to coding.

License

The MIT License (MIT)

About

⏯ Video player, support for caching, preload, fullscreen transition and custom control view. 视频播放器,支持边下边播、预加载、全屏转场和自定义控制层

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages