├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── SGPlayer.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── SGPlayer.xcscmblueprint
└── xcshareddata
│ └── xcschemes
│ ├── SGPlayer iOS.xcscheme
│ ├── SGPlayer macOS.xcscheme
│ └── SGPlayer tvOS.xcscheme
├── SGPlayer
├── Classes
│ ├── Core
│ │ ├── SGAsset
│ │ │ ├── SGAsset+Internal.h
│ │ │ ├── SGAsset.h
│ │ │ ├── SGAsset.m
│ │ │ ├── SGMutableAsset.h
│ │ │ ├── SGMutableAsset.m
│ │ │ ├── SGMutableTrack.h
│ │ │ ├── SGMutableTrack.m
│ │ │ ├── SGPaddingSegment.h
│ │ │ ├── SGPaddingSegment.m
│ │ │ ├── SGSegment+Internal.h
│ │ │ ├── SGSegment.h
│ │ │ ├── SGSegment.m
│ │ │ ├── SGTrack+Internal.h
│ │ │ ├── SGTrack.h
│ │ │ ├── SGTrack.m
│ │ │ ├── SGTrackSelection.h
│ │ │ ├── SGTrackSelection.m
│ │ │ ├── SGURLAsset.h
│ │ │ ├── SGURLAsset.m
│ │ │ ├── SGURLSegment.h
│ │ │ └── SGURLSegment.m
│ │ ├── SGAudio
│ │ │ ├── SGAudioPlayer.h
│ │ │ └── SGAudioPlayer.m
│ │ ├── SGCommon
│ │ │ ├── SGActivity.h
│ │ │ ├── SGActivity.m
│ │ │ ├── SGDefines.h
│ │ │ ├── SGError.h
│ │ │ ├── SGError.m
│ │ │ ├── SGLock.h
│ │ │ ├── SGLock.m
│ │ │ ├── SGTime.h
│ │ │ └── SGTime.m
│ │ ├── SGContainer
│ │ │ ├── SGObjectPool.h
│ │ │ ├── SGObjectPool.m
│ │ │ ├── SGObjectQueue.h
│ │ │ └── SGObjectQueue.m
│ │ ├── SGData
│ │ │ ├── SGAudioFrame.h
│ │ │ ├── SGAudioFrame.m
│ │ │ ├── SGCapacity.h
│ │ │ ├── SGCapacity.m
│ │ │ ├── SGData.h
│ │ │ ├── SGFrame+Internal.h
│ │ │ ├── SGFrame.h
│ │ │ ├── SGFrame.m
│ │ │ ├── SGPacket+Internal.h
│ │ │ ├── SGPacket.h
│ │ │ ├── SGPacket.m
│ │ │ ├── SGTimeLayout.h
│ │ │ ├── SGTimeLayout.m
│ │ │ ├── SGVideoFrame.h
│ │ │ └── SGVideoFrame.m
│ │ ├── SGDecoder
│ │ │ ├── SGAudioDecoder.h
│ │ │ ├── SGAudioDecoder.m
│ │ │ ├── SGCodecContext.h
│ │ │ ├── SGCodecContext.m
│ │ │ ├── SGDecodable.h
│ │ │ ├── SGDecodeContext.h
│ │ │ ├── SGDecodeContext.m
│ │ │ ├── SGDecodeLoop.h
│ │ │ ├── SGDecodeLoop.m
│ │ │ ├── SGVideoDecoder.h
│ │ │ └── SGVideoDecoder.m
│ │ ├── SGDefine
│ │ │ ├── SGMacro.h
│ │ │ ├── SGMapping.h
│ │ │ └── SGMapping.m
│ │ ├── SGDemuxer
│ │ │ ├── SGDemuxable.h
│ │ │ ├── SGExtractingDemuxer.h
│ │ │ ├── SGExtractingDemuxer.m
│ │ │ ├── SGMutilDemuxer.h
│ │ │ ├── SGMutilDemuxer.m
│ │ │ ├── SGPaddingDemuxer.h
│ │ │ ├── SGPaddingDemuxer.m
│ │ │ ├── SGTrackDemuxer.h
│ │ │ ├── SGTrackDemuxer.m
│ │ │ ├── SGURLDemuxer.h
│ │ │ └── SGURLDemuxer.m
│ │ ├── SGDescription
│ │ │ ├── SGAudioDescriptor.h
│ │ │ ├── SGAudioDescriptor.m
│ │ │ ├── SGCodecDescriptor.h
│ │ │ ├── SGCodecDescriptor.m
│ │ │ ├── SGDescriptor+Internal.h
│ │ │ ├── SGVideoDescriptor.h
│ │ │ └── SGVideoDescriptor.m
│ │ ├── SGFFmpeg
│ │ │ ├── SGFFmpeg.h
│ │ │ └── SGFFmpeg.m
│ │ ├── SGMetal
│ │ │ ├── SGMetal.h
│ │ │ ├── SGMetalBGRARenderPipeline.h
│ │ │ ├── SGMetalBGRARenderPipeline.m
│ │ │ ├── SGMetalModel.h
│ │ │ ├── SGMetalModel.m
│ │ │ ├── SGMetalNV12RenderPipeline.h
│ │ │ ├── SGMetalNV12RenderPipeline.m
│ │ │ ├── SGMetalPlaneModel.h
│ │ │ ├── SGMetalPlaneModel.m
│ │ │ ├── SGMetalProjection.h
│ │ │ ├── SGMetalProjection.m
│ │ │ ├── SGMetalRenderPipeline.h
│ │ │ ├── SGMetalRenderPipeline.m
│ │ │ ├── SGMetalRenderPipelinePool.h
│ │ │ ├── SGMetalRenderPipelinePool.m
│ │ │ ├── SGMetalRenderer.h
│ │ │ ├── SGMetalRenderer.m
│ │ │ ├── SGMetalShader.metal
│ │ │ ├── SGMetalShader_iOS.h
│ │ │ ├── SGMetalShader_macOS.h
│ │ │ ├── SGMetalShader_tvOS.h
│ │ │ ├── SGMetalSphereModel.h
│ │ │ ├── SGMetalSphereModel.m
│ │ │ ├── SGMetalTextureLoader.h
│ │ │ ├── SGMetalTextureLoader.m
│ │ │ ├── SGMetalTypes.h
│ │ │ ├── SGMetalViewport.h
│ │ │ ├── SGMetalViewport.m
│ │ │ ├── SGMetalYUVRenderPipeline.h
│ │ │ └── SGMetalYUVRenderPipeline.m
│ │ ├── SGOption
│ │ │ ├── SGDecoderOptions.h
│ │ │ ├── SGDecoderOptions.m
│ │ │ ├── SGDemuxerOptions.h
│ │ │ ├── SGDemuxerOptions.m
│ │ │ ├── SGOptions.h
│ │ │ ├── SGOptions.m
│ │ │ ├── SGProcessorOptions.h
│ │ │ └── SGProcessorOptions.m
│ │ ├── SGPlatform
│ │ │ ├── SGPLFColor.h
│ │ │ ├── SGPLFColor.m
│ │ │ ├── SGPLFImage.h
│ │ │ ├── SGPLFImage.m
│ │ │ ├── SGPLFObject.h
│ │ │ ├── SGPLFScreen.h
│ │ │ ├── SGPLFScreen.m
│ │ │ ├── SGPLFTargets.h
│ │ │ ├── SGPLFView.h
│ │ │ └── SGPLFView.m
│ │ ├── SGProcessor
│ │ │ ├── SGAudioFormatter.h
│ │ │ ├── SGAudioFormatter.m
│ │ │ ├── SGAudioMixer.h
│ │ │ ├── SGAudioMixer.m
│ │ │ ├── SGAudioMixerUnit.h
│ │ │ ├── SGAudioMixerUnit.m
│ │ │ ├── SGAudioProcessor.h
│ │ │ ├── SGAudioProcessor.m
│ │ │ ├── SGProcessor.h
│ │ │ ├── SGSWResample.h
│ │ │ ├── SGSWResample.m
│ │ │ ├── SGSWScale.h
│ │ │ ├── SGSWScale.m
│ │ │ ├── SGSonic.h
│ │ │ ├── SGSonic.m
│ │ │ ├── SGVideoProcessor.h
│ │ │ └── SGVideoProcessor.m
│ │ ├── SGRenderer
│ │ │ ├── SGAudioRenderer.h
│ │ │ ├── SGAudioRenderer.m
│ │ │ ├── SGClock+Internal.h
│ │ │ ├── SGClock.h
│ │ │ ├── SGClock.m
│ │ │ ├── SGRenderTimer.h
│ │ │ ├── SGRenderTimer.m
│ │ │ ├── SGRenderable.h
│ │ │ ├── SGRenderer+Internal.h
│ │ │ ├── SGVideoRenderer.h
│ │ │ └── SGVideoRenderer.m
│ │ ├── SGSession
│ │ │ ├── SGFrameOutput.h
│ │ │ ├── SGFrameOutput.m
│ │ │ ├── SGFrameReader.h
│ │ │ ├── SGFrameReader.m
│ │ │ ├── SGPacketOutput.h
│ │ │ ├── SGPacketOutput.m
│ │ │ ├── SGPlayerItem+Internal.h
│ │ │ ├── SGPlayerItem.h
│ │ │ └── SGPlayerItem.m
│ │ ├── SGVR
│ │ │ ├── SGMotionSensor.h
│ │ │ ├── SGMotionSensor.m
│ │ │ ├── SGVRProjection.h
│ │ │ ├── SGVRProjection.m
│ │ │ ├── SGVRViewport.h
│ │ │ └── SGVRViewport.m
│ │ └── Vendor
│ │ │ └── sonic
│ │ │ ├── sonic.c
│ │ │ └── sonic.h
│ ├── SGPlayer.h
│ ├── SGPlayer.m
│ └── SGPlayerHeader.h
├── Info.plist
└── module.modulemap
├── build.sh
├── demo
├── demo-assset
│ ├── google-help-vr.mp4
│ └── i-see-fire.mp4
├── demo-common
│ ├── SGVideoItem.h
│ └── SGVideoItem.m
├── demo-ios
│ ├── demo-ios.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── demo-ios.xcscheme
│ └── demo-ios
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-Notification@2x.png
│ │ │ ├── Icon-Notification@3x.png
│ │ │ ├── Icon-Small-40@2x.png
│ │ │ ├── Icon-Small-40@3x.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ ├── Icon-Small@3x.png
│ │ │ └── logo.png
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── SGListViewController.h
│ │ ├── SGListViewController.m
│ │ ├── SGPlayViewController.h
│ │ ├── SGPlayViewController.m
│ │ ├── SGPlayViewController.xib
│ │ └── main.m
├── demo-macos
│ ├── demo-macos.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── demo-macos.xcscheme
│ └── demo-macos
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── icon_128x128.png
│ │ │ ├── icon_128x128@2x.png
│ │ │ ├── icon_16x16.png
│ │ │ ├── icon_16x16@2x.png
│ │ │ ├── icon_256x256.png
│ │ │ ├── icon_256x256@2x.png
│ │ │ ├── icon_32x32.png
│ │ │ ├── icon_32x32@2x.png
│ │ │ ├── icon_512x512.png
│ │ │ └── icon_512x512@2x.png
│ │ ├── Base.lproj
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── SGListViewController.h
│ │ ├── SGListViewController.m
│ │ ├── SGPlayViewController.h
│ │ ├── SGPlayViewController.m
│ │ └── main.m
├── demo-tvos
│ ├── demo-tvos.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── demo-tvos.xcscheme
│ └── demo-tvos
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ ├── App Icon & Top Shelf Image.brandassets
│ │ │ ├── App Icon - App Store.imagestack
│ │ │ │ ├── Back.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Front.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Middle.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ ├── App Icon.imagestack
│ │ │ │ ├── Back.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Front.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Middle.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ ├── Top Shelf Image Wide.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Top Shelf Image.imageset
│ │ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── ViewController.h
│ │ ├── ViewController.m
│ │ └── main.m
└── demo.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ ├── IDEWorkspaceChecks.plist
│ └── demo.xcscmblueprint
├── documents
├── banner.jpg
└── flow-chart.jpg
└── scripts
├── avconfig.h
├── compile-ffmpeg.sh
├── compile-openssl.sh
├── config.h
├── do-compile-ffmpeg.sh
├── do-compile-openssl.sh
├── ffversion.h
├── init-ffmpeg.sh
├── init-openssl.sh
├── module.sh
├── pull-repo-base.sh
└── pull-repo-ref.sh
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.h linguist-language=Objective-C
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | *.pbxuser
3 | !default.pbxuser
4 | *.mode1v3
5 | !default.mode1v3
6 | *.mode2v3
7 | !default.mode2v3
8 | *.perspectivev3
9 | !default.perspectivev3
10 | xcuserdata
11 | *.xccheckout
12 | *.moved-aside
13 | DerivedData
14 | *.hmap
15 | *.ipa
16 | *.xcuserstate
17 | .DS_Store
18 | framework/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Single
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 |   
5 |
6 | # SGPlayer
7 |
8 | - SGPlayer is a powerful media play framework for iOS, macOS, and tvOS.
9 |
10 | ## Features
11 |
12 | - iOS, tvOS, macOS.
13 | - 360° panorama video.
14 | - Compose complex asset.
15 | - Background playback.
16 | - RTMP/RTSP streaming.
17 | - Setting playback speed.
18 | - Multiple audio/video tracks.
19 | - H.264/H.265 hardware accelerator.
20 | - Accurate status notifications.
21 | - Thread safety.
22 |
23 | ## Based On
24 |
25 | - FFmpeg
26 | - Metal
27 | - AudioToolbox
28 |
29 | ## Requirements
30 |
31 | - iOS 13.0 or later
32 | - tvOS 13.0 or later
33 | - macOS 10.15 or later
34 |
35 | ## Getting Started
36 |
37 | #### Build FFmpeg and OpenSSL
38 |
39 | - Build scripts are used by default for FFmpeg 4.4.4 and OpenSSL 1.1.1w
40 |
41 | ```obj-c
42 | git clone https://github.com/libobjc/SGPlayer.git
43 | cd SGPlayer
44 | git checkout 2.1.0 -B latest
45 |
46 | // iOS
47 | ./build.sh iOS build
48 |
49 | // tvOS
50 | ./build.sh tvOS build
51 |
52 | // macOS
53 | ./build.sh macOS build
54 | ```
55 |
56 | #### Open demo project in Xcode
57 |
58 | - Open demo/demo.xcworkspace. You can see simple use cases.
59 |
60 | #### Check Dependencies
61 |
62 | ```obj-c
63 | - SGPlayer.framework
64 | - AVFoundation.framework
65 | - AudioToolBox.framework
66 | - VideoToolBox.framework
67 | - libiconv.tbd
68 | - libbz2.tbd
69 | - libz.tbd
70 | ```
71 |
72 | ## Flow Chart
73 |
74 | 
75 |
76 | ## Author
77 |
78 | - GitHub : [Single](https://github.com/libobjc)
79 | - Email : libobjc@gmail.com
80 |
81 | ## Developed by Author
82 |
83 | - [KTVHTTPCache](https://github.com/ChangbaDevs/KTVHTTPCache) - A smart media cache framework.
84 | - [KTVVideoProcess](https://github.com/ChangbaDevs/KTVVideoProcess) - A High-Performance video effects processing framework.
85 |
--------------------------------------------------------------------------------
/SGPlayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <Workspace
3 | version = "1.0">
4 | <FileRef
5 | location = "self:SGPlayer.xcodeproj">
6 | </FileRef>
7 | </Workspace>
8 |
--------------------------------------------------------------------------------
/SGPlayer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 | <plist version="1.0">
4 | <dict>
5 | <key>IDEDidComputeMac32BitWarning</key>
6 | <true/>
7 | </dict>
8 | </plist>
9 |
--------------------------------------------------------------------------------
/SGPlayer.xcodeproj/project.xcworkspace/xcshareddata/SGPlayer.xcscmblueprint:
--------------------------------------------------------------------------------
1 | {
2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "F23AFB690725856BF6A8F7C02C736922AA443A58",
3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4 |
5 | },
6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
7 | "F23AFB690725856BF6A8F7C02C736922AA443A58" : 9223372036854775807,
8 | "CF9A9AD861EDA5D4368DC40F74298A8979BAE8C8" : 9223372036854775807
9 | },
10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "A1C462FA-BB77-480D-B6D6-3CBEF27EAC9D",
11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
12 | "F23AFB690725856BF6A8F7C02C736922AA443A58" : "SGPlayer\/",
13 | "CF9A9AD861EDA5D4368DC40F74298A8979BAE8C8" : "SGPlayer\/Vendors\/SGPlatform\/"
14 | },
15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "SGPlayer",
16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "SGPlayer.xcodeproj",
18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19 | {
20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:0x010101\/SGPlatform.git",
21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "CF9A9AD861EDA5D4368DC40F74298A8979BAE8C8"
23 | },
24 | {
25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:0x010101\/SGPlayer.git",
26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "F23AFB690725856BF6A8F7C02C736922AA443A58"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGAsset+Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAsset+Internal.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/9/25.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGAsset.h"
10 | #import "SGDemuxable.h"
11 |
12 | @interface SGAsset ()
13 |
14 | /*!
15 | @method newDemuxer
16 | @abstract
17 | Create a new demuxer.
18 | */
19 | - (id<SGDemuxable>)newDemuxer;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGAsset.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAsset.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/10.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 |
11 | /*!
12 | @class SGAsset
13 | @abstract
14 | Abstract class for assets.
15 |
16 | @discussion
17 | Use SGURLAsset or SGMutableAsset.
18 | */
19 | @interface SGAsset : NSObject <NSCopying>
20 |
21 | /*!
22 | @method assetWithURL:
23 | @abstract
24 | Returns an instance of SGAsset for inspection of a media resource.
25 | @result
26 | An instance of SGAsset.
27 |
28 | @discussion
29 | Returns a newly allocated instance of a subclass of SGAsset initialized with the specified URL.
30 | */
31 | + (instancetype)assetWithURL:(NSURL *)URL;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGAsset.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGAsset.m
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/10.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGAsset.h"
10 | #import "SGAsset+Internal.h"
11 | #import "SGURLAsset.h"
12 |
13 | @implementation SGAsset
14 |
15 | + (instancetype)assetWithURL:(NSURL *)URL
16 | {
17 | return [[SGURLAsset alloc] initWithURL:URL];
18 | }
19 |
20 | - (id)copyWithZone:(NSZone *)zone
21 | {
22 | SGAsset *obj = [[self.class alloc] init];
23 | return obj;
24 | }
25 |
26 | - (id<SGDemuxable>)newDemuxer
27 | {
28 | NSAssert(NO, @"Subclass only.");
29 | return nil;
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGMutableAsset.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMutableAsset.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/14.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGAsset.h"
10 | #import "SGDefines.h"
11 | #import "SGMutableTrack.h"
12 |
13 | @interface SGMutableAsset : SGAsset
14 |
15 | /*!
16 | @property tracks
17 | @abstract
18 | Provides array of mutable asset tracks.
19 | */
20 | @property (nonatomic, copy, readonly) NSArray<SGMutableTrack *> *tracks;
21 |
22 | /*!
23 | @method addTrack:
24 | @abstract
25 | Add a track to the asset.
26 |
27 | @discussion
28 | Returns a initialized mutable track of the given type.
29 | */
30 | - (SGMutableTrack *)addTrack:(SGMediaType)type;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGMutableAsset.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMutableAsset.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/14.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGMutableAsset.h"
10 | #import "SGAsset+Internal.h"
11 | #import "SGTrack+Internal.h"
12 | #import "SGTrackDemuxer.h"
13 | #import "SGMutilDemuxer.h"
14 |
15 | @interface SGMutableAsset ()
16 |
17 | {
18 | NSMutableArray<SGMutableTrack *> *_tracks;
19 | }
20 |
21 | @end
22 |
23 | @implementation SGMutableAsset
24 |
25 | - (id)copyWithZone:(NSZone *)zone
26 | {
27 | SGMutableAsset *obj = [super copyWithZone:zone];
28 | obj->_tracks = [self->_tracks mutableCopy];
29 | return obj;
30 | }
31 |
32 | - (instancetype)init
33 | {
34 | if (self = [super init]) {
35 | self->_tracks = [NSMutableArray array];
36 | }
37 | return self;
38 | }
39 |
40 | - (NSArray<SGMutableTrack *> *)tracks
41 | {
42 | return [self->_tracks copy];
43 | }
44 |
45 | - (SGMutableTrack *)addTrack:(SGMediaType)type
46 | {
47 | NSInteger index = self->_tracks.count;
48 | SGMutableTrack *obj = [[SGMutableTrack alloc] initWithType:type index:index];
49 | [self->_tracks addObject:obj];
50 | return obj;
51 | }
52 |
53 | - (id<SGDemuxable>)newDemuxer
54 | {
55 | NSMutableArray *demuxables = [NSMutableArray array];
56 | for (SGMutableTrack *obj in self->_tracks) {
57 | SGTrackDemuxer *demuxer = [[SGTrackDemuxer alloc] initWithTrack:obj];
58 | [demuxables addObject:demuxer];
59 | }
60 | return [[SGMutilDemuxer alloc] initWithDemuxables:demuxables];
61 | }
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGMutableTrack.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMutableTrack.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/29.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGSegment.h"
11 | #import "SGTrack.h"
12 |
13 | @interface SGMutableTrack : SGTrack
14 |
15 | /*!
16 | @property subTracks
17 | @abstract
18 | Indicates the sub tracks.
19 | */
20 | @property (nonatomic, copy, readonly) NSArray<SGTrack *> *subTracks;
21 |
22 | /*!
23 | @property segments
24 | @abstract
25 | Provides array of SGMutableTrack segments.
26 | */
27 | @property (nonatomic, copy, readonly) NSArray<SGSegment *> *segments;
28 |
29 | /*!
30 | @method appendSegment:
31 | @abstract
32 | Append a segment to the track.
33 | */
34 | - (BOOL)appendSegment:(SGSegment *)segment;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGMutableTrack.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMutableTrack.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/29.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGMutableTrack.h"
10 | #import "SGTrack+Internal.h"
11 |
12 | @interface SGMutableTrack ()
13 |
14 | {
15 | NSMutableArray<SGSegment *> *_segments;
16 | }
17 |
18 | @end
19 |
20 | @implementation SGMutableTrack
21 |
22 | - (id)copyWithZone:(NSZone *)zone
23 | {
24 | SGMutableTrack *obj = [super copyWithZone:zone];
25 | obj->_segments = [self->_segments mutableCopy];
26 | obj->_subTracks = [self->_subTracks copy];
27 | return obj;
28 | }
29 |
30 | - (instancetype)initWithType:(SGMediaType)type index:(NSInteger)index
31 | {
32 | if (self = [super initWithType:type index:index]) {
33 | self->_segments = [NSMutableArray array];
34 | }
35 | return self;
36 | }
37 |
38 | - (void *)coreptr
39 | {
40 | return [self core];
41 | }
42 |
43 | - (AVStream *)core
44 | {
45 | void *ret = [super core];
46 | if (ret) {
47 | return ret;
48 | }
49 | for (SGTrack *obj in self->_subTracks) {
50 | if (obj.core) {
51 | ret = obj.core;
52 | break;
53 | }
54 | }
55 | return ret;
56 | }
57 |
58 | - (BOOL)appendSegment:(SGSegment *)segment
59 | {
60 | [self->_segments addObject:segment];
61 | return YES;
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGPaddingSegment.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPaddingSegment.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/9/19.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGSegment.h"
10 |
11 | @interface SGPaddingSegment : SGSegment
12 |
13 | + (instancetype)new NS_UNAVAILABLE;
14 | - (instancetype)init NS_UNAVAILABLE;
15 |
16 | /**
17 | *
18 | */
19 | - (instancetype)initWithDuration:(CMTime)duration;
20 |
21 | /**
22 | *
23 | */
24 | @property (nonatomic, readonly) CMTime duration;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGPaddingSegment.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGPaddingSegment.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/9/19.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGPaddingSegment.h"
10 | #import "SGSegment+Internal.h"
11 | #import "SGPaddingDemuxer.h"
12 |
13 | @implementation SGPaddingSegment
14 |
15 | - (id)copyWithZone:(NSZone *)zone
16 | {
17 | SGPaddingSegment *obj = [super copyWithZone:zone];
18 | obj->_duration = self->_duration;
19 | return obj;
20 | }
21 |
22 | - (instancetype)initWithDuration:(CMTime)duration
23 | {
24 | if (self = [super init]) {
25 | self->_duration = duration;
26 | }
27 | return self;
28 | }
29 |
30 | - (NSString *)sharedDemuxerKey
31 | {
32 | return nil;
33 | }
34 |
35 | - (id<SGDemuxable>)newDemuxer
36 | {
37 | return [[SGPaddingDemuxer alloc] initWithDuration:self->_duration];
38 | }
39 |
40 | - (id<SGDemuxable>)newDemuxerWithSharedDemuxer:(id<SGDemuxable>)demuxer
41 | {
42 | return [self newDemuxer];
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGSegment+Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGSegment+Internal.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/9/25.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGSegment.h"
10 | #import "SGDemuxable.h"
11 |
12 | @interface SGSegment ()
13 |
14 | /**
15 | *
16 | */
17 | - (NSString *)sharedDemuxerKey;
18 |
19 | /**
20 | *
21 | */
22 | - (id<SGDemuxable>)newDemuxer;
23 |
24 | /**
25 | *
26 | */
27 | - (id<SGDemuxable>)newDemuxerWithSharedDemuxer:(id<SGDemuxable>)demuxer;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGSegment.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGSegment.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/14.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import <CoreMedia/CoreMedia.h>
11 |
12 | @interface SGSegment : NSObject <NSCopying>
13 |
14 | /*!
15 | @method segmentWithDuration:
16 | @abstract
17 | Returns an instance of SGSegment with the given duration.
18 |
19 | @discussion
20 | For audio track:
21 | *
22 | */
23 | + (instancetype)segmentWithDuration:(CMTime)duration;
24 |
25 | /**
26 | *
27 | */
28 | + (instancetype)segmentWithURL:(NSURL *)URL index:(NSInteger)index;
29 |
30 | /**
31 | *
32 | */
33 | + (instancetype)segmentWithURL:(NSURL *)URL index:(NSInteger)index timeRange:(CMTimeRange)timeRange scale:(CMTime)scale;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGSegment.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGSegment.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/14.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGSegment.h"
10 | #import "SGSegment+Internal.h"
11 | #import "SGPaddingSegment.h"
12 | #import "SGURLSegment.h"
13 |
14 | @implementation SGSegment
15 |
16 | + (instancetype)segmentWithDuration:(CMTime)duration
17 | {
18 | return [[SGPaddingSegment alloc] initWithDuration:duration];
19 | }
20 |
21 | + (instancetype)segmentWithURL:(NSURL *)URL index:(NSInteger)index
22 | {
23 | return [[SGURLSegment alloc] initWithURL:URL index:index timeRange:kCMTimeRangeInvalid scale:kCMTimeInvalid];
24 | }
25 |
26 | + (instancetype)segmentWithURL:(NSURL *)URL index:(NSInteger)index timeRange:(CMTimeRange)timeRange scale:(CMTime)scale
27 | {
28 | return [[SGURLSegment alloc] initWithURL:URL index:index timeRange:timeRange scale:scale];
29 | }
30 |
31 | - (id)copyWithZone:(NSZone *)zone
32 | {
33 | SGSegment *obj = [[self.class alloc] init];
34 | return obj;
35 | }
36 |
37 | - (NSString *)sharedDemuxerKey
38 | {
39 | NSAssert(NO, @"Subclass only.");
40 | return nil;
41 | }
42 |
43 | - (id<SGDemuxable>)newDemuxer
44 | {
45 | NSAssert(NO, @"Subclass only.");
46 | return nil;
47 | }
48 |
49 | - (id<SGDemuxable>)newDemuxerWithSharedDemuxer:(id<SGDemuxable>)demuxer
50 | {
51 | NSAssert(NO, @"Subclass only.");
52 | return nil;
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGTrack+Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGTrack+Internal.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/23.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGTrack.h"
10 | #import "SGFFmpeg.h"
11 | #import "SGMutableTrack.h"
12 |
13 | @interface SGTrack ()
14 |
15 | /*!
16 | @method initWithType:index:
17 | @abstract
18 | Initializes an SGTrack.
19 | */
20 | - (instancetype)initWithType:(SGMediaType)type index:(NSInteger)index;
21 |
22 | /*!
23 | @property core
24 | @abstract
25 | Indicates the pointer to the AVStream.
26 | */
27 | @property (nonatomic) AVStream *core;
28 |
29 | @end
30 |
31 | @interface SGMutableTrack ()
32 |
33 | /*!
34 | @property subTracks
35 | @abstract
36 | Indicates the sub tracks.
37 | */
38 | @property (nonatomic, copy) NSArray<SGTrack *> *subTracks;
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGTrack.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGTrack.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/17.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGDefines.h"
11 |
12 | @interface SGTrack : NSObject <NSCopying>
13 |
14 | + (instancetype)new NS_UNAVAILABLE;
15 | - (instancetype)init NS_UNAVAILABLE;
16 |
17 | /*!
18 | @property coreptr
19 | @abstract
20 | Indicates the pointer to the AVStream.
21 | */
22 | @property (nonatomic, readonly) void *coreptr;
23 |
24 | /*!
25 | @property type
26 | @abstract
27 | Indicates the track media type.
28 | */
29 | @property (nonatomic, readonly) SGMediaType type;
30 |
31 | /*!
32 | @property type
33 | @abstract
34 | Indicates the track index.
35 | */
36 | @property (nonatomic, readonly) NSInteger index;
37 |
38 | /*!
39 | @method trackWithTracks:type:
40 | @abstract
41 | Get track with media type.
42 | */
43 | + (SGTrack *)trackWithTracks:(NSArray<SGTrack *> *)tracks type:(SGMediaType)type;
44 |
45 | /*!
46 | @method trackWithTracks:index:
47 | @abstract
48 | Get track with index.
49 | */
50 | + (SGTrack *)trackWithTracks:(NSArray<SGTrack *> *)tracks index:(NSInteger)index;
51 |
52 | /*!
53 | @method tracksWithTracks:type:
54 | @abstract
55 | Get tracks with media types.
56 | */
57 | + (NSArray<SGTrack *> *)tracksWithTracks:(NSArray<SGTrack *> *)tracks type:(SGMediaType)type;
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGTrack.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGTrack.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/17.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import "SGTrack.h"
10 | #import "SGTrack+Internal.h"
11 |
12 | @implementation SGTrack
13 |
14 | - (id)copyWithZone:(NSZone *)zone
15 | {
16 | SGTrack *obj = [[self.class alloc] init];
17 | obj->_type = self->_type;
18 | obj->_index = self->_index;
19 | obj->_core = self->_core;
20 | return obj;
21 | }
22 |
23 | - (instancetype)initWithType:(SGMediaType)type index:(NSInteger)index
24 | {
25 | if (self = [super init]) {
26 | self->_type = type;
27 | self->_index = index;
28 | }
29 | return self;
30 | }
31 |
32 | - (void *)coreptr
33 | {
34 | return self->_core;
35 | }
36 |
37 | + (SGTrack *)trackWithTracks:(NSArray<SGTrack *> *)tracks type:(SGMediaType)type
38 | {
39 | for (SGTrack *obj in tracks) {
40 | if (obj.type == type) {
41 | return obj;
42 | }
43 | }
44 | return nil;
45 | }
46 |
47 | + (SGTrack *)trackWithTracks:(NSArray<SGTrack *> *)tracks index:(NSInteger)index
48 | {
49 | for (SGTrack *obj in tracks) {
50 | if (obj.index == index) {
51 | return obj;
52 | }
53 | }
54 | return nil;
55 | }
56 |
57 | + (NSArray<SGTrack *> *)tracksWithTracks:(NSArray<SGTrack *> *)tracks type:(SGMediaType)type
58 | {
59 | NSMutableArray *array = [NSMutableArray array];
60 | for (SGTrack *obj in tracks) {
61 | if (obj.type == type) {
62 | [array addObject:obj];
63 | }
64 | }
65 | return array.count ? [array copy] : nil;
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGTrackSelection.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGTrackSelection.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/8/13.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGTrack.h"
11 |
12 | typedef NS_OPTIONS(NSUInteger, SGTrackSelectionAction) {
13 | SGTrackSelectionActionTracks = 1 << 0,
14 | SGTrackSelectionActionWeights = 1 << 1,
15 | };
16 |
17 | @interface SGTrackSelection : NSObject <NSCopying>
18 |
19 | /*!
20 | @property tracks
21 | @abstract
22 | Provides array of SGTrackSelection tracks.
23 | */
24 | @property (nonatomic, copy) NSArray<SGTrack *> *tracks;
25 |
26 | /*!
27 | @property weights
28 | @abstract
29 | Provides array of SGTrackSelection weights.
30 | */
31 | @property (nonatomic, copy) NSArray<NSNumber *> *weights;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGTrackSelection.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGTrackSelection.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/8/13.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGTrackSelection.h"
10 |
11 | @implementation SGTrackSelection
12 |
13 | - (id)copyWithZone:(NSZone *)zone
14 | {
15 | SGTrackSelection *obj = [[SGTrackSelection alloc] init];
16 | obj->_tracks = self->_tracks;
17 | obj->_weights = self->_weights;
18 | return obj;
19 | }
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGURLAsset.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGURLAsset.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/9/19.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGAsset.h"
10 |
11 | @interface SGURLAsset : SGAsset
12 |
13 | + (instancetype)new NS_UNAVAILABLE;
14 | - (instancetype)init NS_UNAVAILABLE;
15 |
16 | /*!
17 | @method initWithURL:
18 | @abstract
19 | Initializes an SGURLAsset with the given URL.
20 | */
21 | - (instancetype)initWithURL:(NSURL *)URL;
22 |
23 | /*!
24 | @property URL
25 | @abstract
26 | Indicates the URL of the asset.
27 | */
28 | @property (nonatomic, copy, readonly) NSURL *URL;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGURLAsset.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGURLAsset.m
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/9/19.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGURLAsset.h"
10 | #import "SGAsset+Internal.h"
11 | #import "SGURLDemuxer.h"
12 |
13 | @implementation SGURLAsset
14 |
15 | - (id)copyWithZone:(NSZone *)zone
16 | {
17 | SGURLAsset *obj = [super copyWithZone:zone];
18 | obj->_URL = [self->_URL copy];
19 | return obj;
20 | }
21 |
22 | - (instancetype)initWithURL:(NSURL *)URL
23 | {
24 | if (self = [super init]) {
25 | self->_URL = [URL copy];
26 | }
27 | return self;
28 | }
29 |
30 | - (id<SGDemuxable>)newDemuxer
31 | {
32 | return [[SGURLDemuxer alloc] initWithURL:self->_URL];
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGURLSegment.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGURLSegment.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/14.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGSegment.h"
10 |
11 | @interface SGURLSegment : SGSegment
12 |
13 | + (instancetype)new NS_UNAVAILABLE;
14 | - (instancetype)init NS_UNAVAILABLE;
15 |
16 | /*!
17 | @method initWithURL:index:timeRange:scale:
18 | @abstract
19 | Initializes an SGURLSegment.
20 | */
21 | - (instancetype)initWithURL:(NSURL *)URL index:(NSInteger)index timeRange:(CMTimeRange)timeRange scale:(CMTime)scale;
22 |
23 | /*!
24 | @property URL
25 | @abstract
26 | Indicates the URL of the segment.
27 | */
28 | @property (nonatomic, copy, readonly) NSURL *URL;
29 |
30 | /*!
31 | @property type
32 | @abstract
33 | Indicates the index.
34 | */
35 | @property (nonatomic, readonly) NSInteger index;
36 |
37 | /*!
38 | @property timeRange
39 | @abstract
40 | Indicates the timeRange of the segment.
41 | */
42 | @property (nonatomic, readonly) CMTimeRange timeRange;
43 |
44 | /*!
45 | @property scale
46 | @abstract
47 | Indicates the scale of the segment.
48 | */
49 | @property (nonatomic, readonly) CMTime scale;
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAsset/SGURLSegment.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGURLSegment.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/14.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGURLSegment.h"
10 | #import "SGSegment+Internal.h"
11 | #import "SGExtractingDemuxer.h"
12 | #import "SGURLDemuxer.h"
13 | #import "SGTime.h"
14 |
15 | @implementation SGURLSegment
16 |
17 | - (id)copyWithZone:(NSZone *)zone
18 | {
19 | SGURLSegment *obj = [super copyWithZone:zone];
20 | obj->_URL = [self->_URL copy];
21 | obj->_index = self->_index;
22 | obj->_timeRange = self->_timeRange;
23 | obj->_scale = self->_scale;
24 | return obj;
25 | }
26 |
27 | - (instancetype)initWithURL:(NSURL *)URL index:(NSInteger)index timeRange:(CMTimeRange)timeRange scale:(CMTime)scale
28 | {
29 | scale = SGCMTimeValidate(scale, CMTimeMake(1, 1), NO);
30 | NSAssert(CMTimeCompare(scale, CMTimeMake(1, 10)) >= 0, @"Invalid Scale.");
31 | NSAssert(CMTimeCompare(scale, CMTimeMake(10, 1)) <= 0, @"Invalid Scale.");
32 | if (self = [super init]) {
33 | self->_URL = [URL copy];
34 | self->_index = index;
35 | self->_timeRange = timeRange;
36 | self->_scale = scale;
37 | }
38 | return self;
39 | }
40 |
41 | - (NSString *)sharedDemuxerKey
42 | {
43 | return self->_URL.isFileURL ? self->_URL.path : self->_URL.absoluteString;
44 | }
45 |
46 | - (id<SGDemuxable>)newDemuxer
47 | {
48 | return [self newDemuxerWithSharedDemuxer:nil];
49 | }
50 |
51 | - (id<SGDemuxable>)newDemuxerWithSharedDemuxer:(id<SGDemuxable>)demuxer
52 | {
53 | if (!demuxer) {
54 | demuxer = [[SGURLDemuxer alloc] initWithURL:self->_URL];
55 | }
56 | SGExtractingDemuxer *obj = [[SGExtractingDemuxer alloc] initWithDemuxable:demuxer index:self->_index timeRange:self->_timeRange scale:self->_scale];
57 | return obj;
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGAudio/SGAudioPlayer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioPlayer.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/16.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import <AudioToolbox/AudioToolbox.h>
11 |
12 | @class SGAudioPlayer;
13 |
14 | @protocol SGAudioPlayerDelegate <NSObject>
15 |
16 | /**
17 | *
18 | */
19 | - (void)audioPlayer:(SGAudioPlayer *)player render:(const AudioTimeStamp *)timeStamp data:(AudioBufferList *)data numberOfFrames:(UInt32)numberOfFrames;
20 |
21 | @optional
22 | /**
23 | *
24 | */
25 | - (void)audioPlayer:(SGAudioPlayer *)player willRender:(const AudioTimeStamp *)timestamp;
26 |
27 | /**
28 | *
29 | */
30 | - (void)audioPlayer:(SGAudioPlayer *)player didRender:(const AudioTimeStamp *)timestamp;
31 |
32 | @end
33 |
34 | @interface SGAudioPlayer : NSObject
35 |
36 | /**
37 | * Delegate.
38 | */
39 | @property (nonatomic, weak) id<SGAudioPlayerDelegate> delegate;
40 |
41 | /**
42 | * Rate.
43 | */
44 | @property (nonatomic) float rate;
45 |
46 | /**
47 | * Pitch.
48 | */
49 | @property (nonatomic) float pitch;
50 |
51 | /**
52 | * Volume.
53 | */
54 | @property (nonatomic) float volume;
55 |
56 | /**
57 | * ASBD.
58 | */
59 | @property (nonatomic) AudioStreamBasicDescription asbd;
60 |
61 | /**
62 | * Playback.
63 | */
64 | - (BOOL)isPlaying;
65 |
66 | /**
67 | * Play.
68 | */
69 | - (void)play;
70 |
71 | /**
72 | * Pause.
73 | */
74 | - (void)pause;
75 |
76 | /**
77 | * Flush.
78 | */
79 | - (void)flush;
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGCommon/SGActivity.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPlayerActivity.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/10.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 |
11 | @interface SGActivity : NSObject
12 |
13 | /**
14 | *
15 | */
16 | + (void)addTarget:(id)target;
17 |
18 | /**
19 | *
20 | */
21 | + (void)removeTarget:(id)target;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGCommon/SGActivity.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGPlayerActivity.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/10.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import "SGActivity.h"
10 |
11 | @interface SGActivity ()
12 |
13 | @property (nonatomic, strong, readonly) NSLock *lock;
14 | @property (nonatomic, strong, readonly) NSMutableSet *targets;
15 |
16 | @end
17 |
18 | @implementation SGActivity
19 |
20 | + (void)addTarget:(id)target
21 | {
22 | [[SGActivity activity] addTarget:target];
23 | }
24 |
25 | + (void)removeTarget:(id)target
26 | {
27 | [[SGActivity activity] removeTarget:target];
28 | }
29 |
30 | + (instancetype)activity
31 | {
32 | static SGActivity *obj = nil;
33 | static dispatch_once_t onceToken;
34 | dispatch_once(&onceToken, ^{
35 | obj = [[SGActivity alloc] init];
36 | });
37 | return obj;
38 | }
39 |
40 | - (instancetype)init
41 | {
42 | if (self = [super init]) {
43 | self->_lock = [[NSLock alloc] init];
44 | self->_targets = [NSMutableSet set];
45 | }
46 | return self;
47 | }
48 |
49 | - (void)addTarget:(id)target
50 | {
51 | if (!target) {
52 | return;
53 | }
54 | [self->_lock lock];
55 | if (![self->_targets containsObject:[self token:target]]) {
56 | [self->_targets addObject:[self token:target]];
57 | }
58 | [self reload];
59 | [self->_lock unlock];
60 | }
61 |
62 | - (void)removeTarget:(id)target
63 | {
64 | if (!target) {
65 | return;
66 | }
67 | [self->_lock lock];
68 | if ([self->_targets containsObject:[self token:target]]) {
69 | [self->_targets removeObject:[self token:target]];
70 | }
71 | [self reload];
72 | [self->_lock unlock];
73 | }
74 |
75 | - (void)reload
76 | {
77 | #if SGPLATFORM_TARGET_OS_IPHONE_OR_TV
78 | BOOL disable = self.objects.count <= 0;
79 | dispatch_async(dispatch_get_main_queue(), ^{
80 | [UIApplication sharedApplication].idleTimerDisabled = disable;
81 | });
82 | #endif
83 | }
84 |
85 | - (id)token:(id)target
86 | {
87 | return [NSString stringWithFormat:@"%p", target];
88 | }
89 |
90 | @end
91 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGCommon/SGDefines.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGDefines.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/6/25.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import <CoreMedia/CoreMedia.h>
11 |
12 | #if defined(__cplusplus)
13 | #define SGPLAYER_EXTERN extern "C"
14 | #else
15 | #define SGPLAYER_EXTERN extern
16 | #endif
17 |
18 | typedef NS_ENUM(NSUInteger, SGMediaType) {
19 | SGMediaTypeUnknown = 0,
20 | SGMediaTypeAudio = 1,
21 | SGMediaTypeVideo = 2,
22 | SGMediaTypeSubtitle = 3,
23 | };
24 |
25 | typedef NS_ENUM(NSUInteger, SGPlayerState) {
26 | SGPlayerStateNone = 0,
27 | SGPlayerStatePreparing = 1,
28 | SGPlayerStateReady = 2,
29 | SGPlayerStateFailed = 3,
30 | };
31 |
32 | typedef NS_OPTIONS(NSUInteger, SGPlaybackState) {
33 | SGPlaybackStateNone = 0,
34 | SGPlaybackStatePlaying = 1 << 0,
35 | SGPlaybackStateSeeking = 1 << 1,
36 | SGPlaybackStateFinished = 1 << 2,
37 | };
38 |
39 | typedef NS_ENUM(NSUInteger, SGLoadingState) {
40 | SGLoadingStateNone = 0,
41 | SGLoadingStatePlaybale = 1,
42 | SGLoadingStateStalled = 2,
43 | SGLoadingStateFinished = 3,
44 | };
45 |
46 | typedef NS_OPTIONS(NSUInteger, SGInfoAction) {
47 | SGInfoActionNone = 0,
48 | SGInfoActionTimeCached = 1 << 1,
49 | SGInfoActionTimePlayback = 1 << 2,
50 | SGInfoActionTimeDuration = 1 << 3,
51 | SGInfoActionTime = SGInfoActionTimeCached | SGInfoActionTimePlayback | SGInfoActionTimeDuration,
52 | SGInfoActionStatePlayer = 1 << 4,
53 | SGInfoActionStateLoading = 1 << 5,
54 | SGInfoActionStatePlayback = 1 << 6,
55 | SGInfoActionState = SGInfoActionStatePlayer | SGInfoActionStateLoading | SGInfoActionStatePlayback,
56 | };
57 |
58 | typedef struct {
59 | int num;
60 | int den;
61 | } SGRational;
62 |
63 | typedef struct {
64 | CMTime cached;
65 | CMTime playback;
66 | CMTime duration;
67 | } SGTimeInfo;
68 |
69 | typedef struct {
70 | SGPlayerState player;
71 | SGLoadingState loading;
72 | SGPlaybackState playback;
73 | } SGStateInfo;
74 |
75 | @class SGPlayer;
76 |
77 | typedef void (^SGBlock)(void);
78 | typedef void (^SGHandler)(SGPlayer *player);
79 | typedef BOOL (^SGTimeReader)(CMTime *desire, BOOL *drop);
80 | typedef void (^SGSeekResult)(CMTime time, NSError *error);
81 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGCommon/SGError.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGError.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/16.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 |
11 | typedef NS_ENUM(NSUInteger, SGErrorCode) {
12 | SGErrorCodeUnknown = 0,
13 | SGErrorImmediateExitRequested,
14 | SGErrorCodeNoValidFormat,
15 | SGErrorCodeFormatNotSeekable,
16 | SGErrorCodePacketOutputCancelSeek,
17 | SGErrorCodeDemuxerEndOfFile,
18 | SGErrorCodeInvlidTime,
19 | };
20 |
21 | typedef NS_ENUM(NSUInteger, SGActionCode) {
22 | SGActionCodeUnknown = 0,
23 | SGActionCodeFormatCreate,
24 | SGActionCodeFormatOpenInput,
25 | SGActionCodeFormatFindStreamInfo,
26 | SGActionCodeFormatSeekFrame,
27 | SGActionCodeFormatReadFrame,
28 | SGActionCodeFormatGetSeekable,
29 | SGActionCodeCodecSetParametersToContext,
30 | SGActionCodeCodecOpen2,
31 | SGActionCodePacketOutputSeek,
32 | SGActionCodeURLDemuxerFunnelNext,
33 | SGActionCodeMutilDemuxerNext,
34 | SGActionCodeSegmentDemuxerNext,
35 | SGActionCodeNextFrame,
36 | };
37 |
38 | NSError * SGGetFFError(int result, SGActionCode operation);
39 | NSError * SGCreateError(NSUInteger code, SGActionCode operation);
40 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGCommon/SGError.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGError.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/16.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import "SGError.h"
10 | #import "SGFFmpeg.h"
11 |
12 | static NSString * const SGErrorUserInfoKeyOperation = @"SGErrorUserInfoKeyOperation";
13 |
14 | NSError * SGGetFFError(int result, SGActionCode operation)
15 | {
16 | if (result >= 0) {
17 | return nil;
18 | }
19 | char *data = malloc(256);
20 | av_strerror(result, data, 256);
21 | NSString *domain = [NSString stringWithFormat:@"SGPlayer-Error-FFmpeg code : %d, msg : %s", result, data];
22 | free(data);
23 | if (result == AVERROR_EXIT) {
24 | result = SGErrorImmediateExitRequested;
25 | } else if (result == AVERROR_EOF) {
26 | result = SGErrorCodeDemuxerEndOfFile;
27 | }
28 | return [NSError errorWithDomain:domain code:result userInfo:@{SGErrorUserInfoKeyOperation : @(operation)}];
29 | }
30 |
31 | NSError * SGCreateError(NSUInteger code, SGActionCode operation)
32 | {
33 | return [NSError errorWithDomain:@"SGPlayer-Error-SGErrorCode" code:(NSInteger)code userInfo:@{SGErrorUserInfoKeyOperation : @(operation)}];
34 | }
35 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGCommon/SGLock.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGLock.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/29.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGDefines.h"
11 |
12 | BOOL SGLockEXE00(id<NSLocking> locking, void (^run)(void));
13 | BOOL SGLockEXE10(id<NSLocking> locking, SGBlock (^run)(void));
14 | BOOL SGLockEXE11(id<NSLocking> locking, SGBlock (^run)(void), BOOL (^finish)(SGBlock block));
15 |
16 | BOOL SGLockCondEXE00(id<NSLocking> locking, BOOL (^verify)(void), void (^run)(void));
17 | BOOL SGLockCondEXE10(id<NSLocking> locking, BOOL (^verify)(void), SGBlock (^run)(void));
18 | BOOL SGLockCondEXE11(id<NSLocking> locking, BOOL (^verify)(void), SGBlock (^run)(void), BOOL (^finish)(SGBlock block));
19 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGCommon/SGLock.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGLock.m
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/29.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGLock.h"
10 |
11 | BOOL SGLockEXE00(id<NSLocking> locking, void (^run)(void))
12 | {
13 | [locking lock];
14 | if (run) {
15 | run();
16 | }
17 | [locking unlock];
18 | return YES;
19 | }
20 |
21 | BOOL SGLockEXE10(id<NSLocking> locking, SGBlock (^run)(void))
22 | {
23 | [locking lock];
24 | SGBlock r = nil;
25 | if (run) {
26 | r = run();
27 | }
28 | [locking unlock];
29 | if (r) {
30 | r();
31 | }
32 | return YES;
33 | }
34 |
35 | BOOL SGLockEXE11(id<NSLocking> locking, SGBlock (^run)(void), BOOL (^finish)(SGBlock block))
36 | {
37 | [locking lock];
38 | SGBlock r = nil;
39 | if (run) {
40 | r = run();
41 | }
42 | [locking unlock];
43 | if (finish) {
44 | return finish(r ? r : ^{});
45 | } else if (r) {
46 | r();
47 | }
48 | return YES;
49 | }
50 |
51 | BOOL SGLockCondEXE00(id<NSLocking> locking, BOOL (^verify)(void), void (^run)(void))
52 | {
53 | [locking lock];
54 | BOOL s = YES;
55 | if (verify) {
56 | s = verify();
57 | }
58 | if (!s) {
59 | [locking unlock];
60 | return NO;
61 | }
62 | if (run) {
63 | run();
64 | }
65 | [locking unlock];
66 | return YES;
67 | }
68 |
69 | BOOL SGLockCondEXE10(id<NSLocking> locking, BOOL (^verify)(void), SGBlock (^run)(void))
70 | {
71 | [locking lock];
72 | BOOL s = YES;
73 | if (verify) {
74 | s = verify();
75 | }
76 | if (!s) {
77 | [locking unlock];
78 | return NO;
79 | }
80 | SGBlock r = nil;
81 | if (run) {
82 | r = run();
83 | }
84 | [locking unlock];
85 | if (r) {
86 | r();
87 | }
88 | return YES;
89 | }
90 |
91 | BOOL SGLockCondEXE11(id<NSLocking> locking, BOOL (^verify)(void), SGBlock (^run)(void), BOOL (^finish)(SGBlock block))
92 | {
93 | [locking lock];
94 | BOOL s = YES;
95 | if (verify) {
96 | s = verify();
97 | }
98 | if (!s) {
99 | [locking unlock];
100 | return NO;
101 | }
102 | SGBlock r = nil;
103 | if (run) {
104 | r = run();
105 | }
106 | [locking unlock];
107 | if (finish) {
108 | return finish(r ? r : ^{});
109 | } else if (r) {
110 | r();
111 | }
112 | return YES;
113 | }
114 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGCommon/SGTime.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGTime.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/6/13.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import <CoreMedia/CoreMedia.h>
11 |
12 | BOOL SGCMTimeIsValid(CMTime time, BOOL infinity);
13 |
14 | CMTime SGCMTimeValidate(CMTime time, CMTime defaultTime, BOOL infinity);
15 | CMTime SGCMTimeMakeWithSeconds(Float64 seconds);
16 | CMTime SGCMTimeMultiply(CMTime time, CMTime multiplier);
17 | CMTime SGCMTimeDivide(CMTime time, CMTime divisor);
18 | CMTime SGCMTimeDivide(CMTime time, CMTime divisor);
19 |
20 | CMTimeRange SGCMTimeRangeFitting(CMTimeRange timeRange);
21 | CMTimeRange SGCMTimeRangeGetIntersection(CMTimeRange timeRange1, CMTimeRange timeRange2);
22 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGContainer/SGObjectPool.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGObjectPool.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/22.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGData.h"
11 |
12 | @interface SGObjectPool : NSObject
13 |
14 | + (instancetype)sharedPool;
15 |
16 | /**
17 | *
18 | */
19 | - (__kindof id<SGData>)objectWithClass:(Class)class reuseName:(NSString *)reuseName;
20 |
21 | /**
22 | *
23 | */
24 | - (void)comeback:(id<SGData>)object;
25 |
26 | /**
27 | *
28 | */
29 | - (void)flush;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGContainer/SGObjectPool.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGObjectPool.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/22.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import "SGObjectPool.h"
10 |
11 | @interface SGObjectPool ()
12 |
13 | @property (nonatomic, strong, readonly) NSLock *lock;
14 | @property (nonatomic, strong, readonly) NSMutableDictionary<NSString *, NSMutableSet<id<SGData>> *> *pool;
15 |
16 | @end
17 |
18 | @implementation SGObjectPool
19 |
20 | + (instancetype)sharedPool
21 | {
22 | static SGObjectPool *obj = nil;
23 | static dispatch_once_t onceToken;
24 | dispatch_once(&onceToken, ^{
25 | obj = [[SGObjectPool alloc] init];
26 | });
27 | return obj;
28 | }
29 |
30 | - (instancetype)init
31 | {
32 | if (self = [super init]) {
33 | self->_lock = [[NSLock alloc] init];
34 | self->_pool = [NSMutableDictionary dictionary];
35 | }
36 | return self;
37 | }
38 |
39 | - (id<SGData>)objectWithClass:(Class)class reuseName:(NSString *)reuseName
40 | {
41 | [self->_lock lock];
42 | NSMutableSet <id<SGData>> *set = [self->_pool objectForKey:reuseName];
43 | if (!set) {
44 | set = [NSMutableSet set];
45 | [self->_pool setObject:set forKey:reuseName];
46 | }
47 | id<SGData> object = set.anyObject;
48 | if (object) {
49 | [set removeObject:object];
50 | } else {
51 | object = [[class alloc] init];
52 | }
53 | [object lock];
54 | object.reuseName = reuseName;
55 | [self->_lock unlock];
56 | return object;
57 | }
58 |
59 | - (void)comeback:(id<SGData>)object
60 | {
61 | [self->_lock lock];
62 | NSMutableSet <id<SGData>> *set = [self->_pool objectForKey:object.reuseName];
63 | if (![set containsObject:object]) {
64 | [set addObject:object];
65 | [object clear];
66 | }
67 | [self->_lock unlock];
68 | }
69 |
70 | - (void)flush
71 | {
72 | [self->_lock lock];
73 | [self->_pool removeAllObjects];
74 | [self->_lock unlock];
75 | }
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGContainer/SGObjectQueue.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGObjectQueue.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/22.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGCapacity.h"
11 | #import "SGDefines.h"
12 | #import "SGData.h"
13 |
14 | @interface SGObjectQueue : NSObject
15 |
16 | /**
17 | *
18 | */
19 | - (instancetype)initWithMaxCount:(uint64_t)maxCount;
20 |
21 | /**
22 | *
23 | */
24 | @property (nonatomic) BOOL shouldSortObjects;
25 |
26 | /**
27 | *
28 | */
29 | - (SGCapacity)capacity;
30 |
31 | /**
32 | *
33 | */
34 | - (BOOL)putObjectSync:(id<SGData>)object;
35 | - (BOOL)putObjectSync:(id<SGData>)object before:(SGBlock)before after:(SGBlock)after;
36 |
37 | /**
38 | *
39 | */
40 | - (BOOL)putObjectAsync:(id<SGData>)object;
41 |
42 | /**
43 | *
44 | */
45 | - (BOOL)getObjectSync:(id<SGData> *)object;
46 | - (BOOL)getObjectSync:(id<SGData> *)object before:(SGBlock)before after:(SGBlock)after;
47 |
48 | /**
49 | *
50 | */
51 | - (BOOL)getObjectAsync:(id<SGData> *)object;
52 | - (BOOL)getObjectAsync:(id<SGData> *)object timeReader:(SGTimeReader)timeReader discarded:(uint64_t *)discarded;
53 |
54 | /**
55 | *
56 | */
57 | - (BOOL)flush;
58 |
59 | /**
60 | *
61 | */
62 | - (BOOL)destroy;
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGAudioFrame.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioFrame.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/19.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import "SGFrame.h"
10 | #import "SGAudioDescriptor.h"
11 |
12 | @interface SGAudioFrame : SGFrame
13 |
14 | /**
15 | *
16 | */
17 | @property (nonatomic, strong, readonly) SGAudioDescriptor *descriptor;
18 |
19 | /**
20 | *
21 | */
22 | @property (nonatomic, readonly) int numberOfSamples;
23 |
24 | /**
25 | *
26 | */
27 | - (int *)linesize;
28 |
29 | /**
30 | *
31 | */
32 | - (uint8_t **)data;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGCapacity.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGCapacity.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/25.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGTime.h"
11 |
12 | typedef struct SGCapacity {
13 | int size;
14 | int count;
15 | CMTime duration;
16 | } SGCapacity;
17 |
18 | SGCapacity SGCapacityCreate(void);
19 | SGCapacity SGCapacityAdd(SGCapacity c1, SGCapacity c2);
20 | SGCapacity SGCapacityMinimum(SGCapacity c1, SGCapacity c2);
21 | SGCapacity SGCapacityMaximum(SGCapacity c1, SGCapacity c2);
22 |
23 | BOOL SGCapacityIsEqual(SGCapacity c1, SGCapacity c2);
24 | BOOL SGCapacityIsEnough(SGCapacity c1);
25 | BOOL SGCapacityIsEmpty(SGCapacity c1);
26 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGCapacity.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGCapacity.m
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/25.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGCapacity.h"
10 |
11 | SGCapacity SGCapacityCreate(void)
12 | {
13 | SGCapacity ret;
14 | ret.size = 0;
15 | ret.count = 0;
16 | ret.duration = kCMTimeZero;
17 | return ret;
18 | }
19 |
20 | SGCapacity SGCapacityAdd(SGCapacity c1, SGCapacity c2)
21 | {
22 | SGCapacity ret = SGCapacityCreate();
23 | ret.size = c1.size + c2.size;
24 | ret.count = c1.count + c2.count;
25 | ret.duration = CMTimeAdd(c1.duration, c2.duration);
26 | return ret;
27 | }
28 |
29 | SGCapacity SGCapacityMinimum(SGCapacity c1, SGCapacity c2)
30 | {
31 | if (CMTimeCompare(c1.duration, c2.duration) < 0) {
32 | return c1;
33 | } else if (CMTimeCompare(c1.duration, c2.duration) > 0) {
34 | return c1;
35 | }
36 | if (c1.count < c2.count) {
37 | return c1;
38 | } else if (c1.count > c2.count) {
39 | return c2;
40 | }
41 | if (c1.size < c2.size) {
42 | return c1;
43 | } else if (c1.size > c2.size) {
44 | return c2;
45 | }
46 | return c1;
47 | }
48 |
49 | SGCapacity SGCapacityMaximum(SGCapacity c1, SGCapacity c2)
50 | {
51 | if (CMTimeCompare(c1.duration, c2.duration) < 0) {
52 | return c2;
53 | } else if (CMTimeCompare(c1.duration, c2.duration) > 0) {
54 | return c1;
55 | }
56 | if (c1.count < c2.count) {
57 | return c2;
58 | } else if (c1.count > c2.count) {
59 | return c1;
60 | }
61 | if (c1.size < c2.size) {
62 | return c2;
63 | } else if (c1.size > c2.size) {
64 | return c1;
65 | }
66 | return c1;
67 | }
68 |
69 | BOOL SGCapacityIsEqual(SGCapacity c1, SGCapacity c2)
70 | {
71 | return
72 | c1.size == c2.size &&
73 | c1.count == c2.count &&
74 | CMTimeCompare(c1.duration, c2.duration) == 0;
75 | }
76 |
77 | BOOL SGCapacityIsEnough(SGCapacity c1)
78 | {
79 | /*
80 | return
81 | c1.count >= 30 &&
82 | CMTimeCompare(c1.duration, CMTimeMake(1, 1)) > 0;
83 | */
84 | return
85 | c1.count >= 50000;
86 | }
87 |
88 | BOOL SGCapacityIsEmpty(SGCapacity c1)
89 | {
90 | return
91 | c1.size == 0 &&
92 | c1.count == 0 &&
93 | (CMTIME_IS_INVALID(c1.duration) ||
94 | CMTimeCompare(c1.duration, kCMTimeZero) == 0);
95 | }
96 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGData.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGDemuxable.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/9/25.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import <CoreMedia/CoreMedia.h>
11 |
12 | /**
13 | *
14 | */
15 | typedef NS_OPTIONS(NSUInteger, SGDataFlags) {
16 | SGDataFlagPadding = 1 << 0,
17 | };
18 |
19 | @protocol SGData <NSObject>
20 |
21 | /**
22 | *
23 | */
24 | @property (nonatomic) SGDataFlags flags;
25 |
26 | /**
27 | *
28 | */
29 | @property (nonatomic, copy) NSString *reuseName;
30 |
31 | /**
32 | *
33 | */
34 | - (void)lock;
35 |
36 | /**
37 | *
38 | */
39 | - (void)unlock;
40 |
41 | /**
42 | *
43 | */
44 | - (void)clear;
45 |
46 | /**
47 | *
48 | */
49 | - (CMTime)duration;
50 |
51 | /**
52 | *
53 | */
54 | - (CMTime)timeStamp;
55 |
56 | /**
57 | *
58 | */
59 | - (int)size;
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGFrame+Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGFrame+Internal.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/23.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGFrame.h"
10 | #import "SGAudioFrame.h"
11 | #import "SGVideoFrame.h"
12 | #import "SGCodecDescriptor.h"
13 |
14 | @interface SGFrame ()
15 |
16 | /**
17 | *
18 | */
19 | + (instancetype)frame;
20 |
21 | /**
22 | *
23 | */
24 | @property (nonatomic, readonly) AVFrame *core;
25 |
26 | /**
27 | *
28 | */
29 | @property (nonatomic, strong) SGCodecDescriptor *codecDescriptor;
30 |
31 | /**
32 | *
33 | */
34 | - (void)fill;
35 |
36 | /**
37 | *
38 | */
39 | - (void)fillWithFrame:(SGFrame *)frame;
40 |
41 | /**
42 | *
43 | */
44 | - (void)fillWithTimeStamp:(CMTime)timeStamp decodeTimeStamp:(CMTime)decodeTimeStamp duration:(CMTime)duration;
45 |
46 | @end
47 |
48 | @interface SGAudioFrame ()
49 |
50 | /**
51 | *
52 | */
53 | + (instancetype)frameWithDescriptor:(SGAudioDescriptor *)descriptor numberOfSamples:(int)numberOfSamples;
54 |
55 | @end
56 |
57 | @interface SGVideoFrame ()
58 |
59 | /**
60 | *
61 | */
62 | + (instancetype)frameWithDescriptor:(SGVideoDescriptor *)descriptor;
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGFrame.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGFrame.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/18.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGTrack.h"
11 | #import "SGData.h"
12 |
13 | static int const SGFramePlaneCount = 8;
14 |
15 | @interface SGFrame : NSObject <SGData>
16 |
17 | /**
18 | *
19 | */
20 | @property (nonatomic, readonly) void *coreptr;
21 |
22 | /**
23 | *
24 | */
25 | @property (nonatomic, strong, readonly) SGTrack *track;
26 |
27 | /**
28 | *
29 | */
30 | @property (nonatomic, strong, readonly) NSDictionary *metadata;
31 |
32 | /**
33 | *
34 | */
35 | @property (nonatomic, readonly) CMTime duration;
36 |
37 | /**
38 | *
39 | */
40 | @property (nonatomic, readonly) CMTime timeStamp;
41 |
42 | /**
43 | *
44 | */
45 | @property (nonatomic, readonly) CMTime decodeTimeStamp;
46 |
47 | /**
48 | *
49 | */
50 | @property (nonatomic, readonly) int size;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGPacket+Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPacket+Internal.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/23.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGPacket.h"
10 | #import "SGCodecDescriptor.h"
11 |
12 | @interface SGPacket ()
13 |
14 | /**
15 | *
16 | */
17 | + (instancetype)packet;
18 |
19 | /**
20 | *
21 | */
22 | @property (nonatomic, readonly) AVPacket *core;
23 |
24 | /**
25 | *
26 | */
27 | @property (nonatomic, strong) SGCodecDescriptor *codecDescriptor;
28 |
29 | /**
30 | *
31 | */
32 | - (void)fill;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGPacket.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPacket.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/22.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGTrack.h"
11 | #import "SGData.h"
12 |
13 | @interface SGPacket : NSObject <SGData>
14 |
15 | /**
16 | *
17 | */
18 | @property (nonatomic, readonly) void *coreptr;
19 |
20 | /**
21 | *
22 | */
23 | @property (nonatomic, strong, readonly) SGTrack *track;
24 |
25 | /**
26 | *
27 | */
28 | @property (nonatomic, strong, readonly) NSDictionary *metadata;
29 |
30 | /**
31 | *
32 | */
33 | @property (nonatomic, readonly) CMTime duration;
34 |
35 | /**
36 | *
37 | */
38 | @property (nonatomic, readonly) CMTime timeStamp;
39 |
40 | /**
41 | *
42 | */
43 | @property (nonatomic, readonly) CMTime decodeTimeStamp;
44 |
45 | /**
46 | *
47 | */
48 | @property (nonatomic, readonly) int size;
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGTimeLayout.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGTimeLayout.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/15.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGTime.h"
11 |
12 | @interface SGTimeLayout : NSObject <NSCopying>
13 |
14 | /**
15 | *
16 | */
17 | - (instancetype)initWithScale:(CMTime)scale;
18 |
19 | /**
20 | *
21 | */
22 | - (instancetype)initWithOffset:(CMTime)offset;
23 |
24 | /**
25 | *
26 | */
27 | @property (nonatomic, readonly) CMTime scale;
28 |
29 | /**
30 | *
31 | */
32 | @property (nonatomic, readonly) CMTime offset;
33 |
34 | /**
35 | *
36 | */
37 | - (CMTime)convertDuration:(CMTime)duration;
38 |
39 | /**
40 | *
41 | */
42 | - (CMTime)convertTimeStamp:(CMTime)timeStamp;
43 |
44 | /**
45 | *
46 | */
47 | - (CMTime)reconvertTimeStamp:(CMTime)timeStamp;
48 |
49 | /**
50 | *
51 | */
52 | - (BOOL)isEqualToTimeLayout:(SGTimeLayout *)timeLayout;
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGTimeLayout.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGTimeLayout.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/15.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGTimeLayout.h"
10 |
11 | @implementation SGTimeLayout
12 |
13 | - (id)copyWithZone:(NSZone *)zone
14 | {
15 | SGTimeLayout *obj = [[SGTimeLayout alloc] init];
16 | obj->_scale = self->_scale;
17 | obj->_offset = self->_offset;
18 | return obj;
19 | }
20 |
21 | - (instancetype)initWithScale:(CMTime)scale
22 | {
23 | if (self = [super init]) {
24 | self->_scale = SGCMTimeValidate(scale, CMTimeMake(1, 1), NO);
25 | self->_offset = kCMTimeInvalid;
26 | }
27 | return self;
28 | }
29 |
30 | - (instancetype)initWithOffset:(CMTime)offset
31 | {
32 | if (self = [super init]) {
33 | self->_scale = kCMTimeInvalid;
34 | self->_offset = SGCMTimeValidate(offset, kCMTimeZero, NO);
35 | }
36 | return self;
37 | }
38 |
39 | - (CMTime)convertDuration:(CMTime)duration
40 | {
41 | if (CMTIME_IS_NUMERIC(self->_scale)) {
42 | duration = SGCMTimeMultiply(duration, self->_scale);
43 | }
44 | return duration;
45 | }
46 |
47 | - (CMTime)convertTimeStamp:(CMTime)timeStamp
48 | {
49 | if (CMTIME_IS_NUMERIC(self->_scale)) {
50 | timeStamp = SGCMTimeMultiply(timeStamp, self->_scale);
51 | }
52 | if (CMTIME_IS_NUMERIC(self->_offset)) {
53 | timeStamp = CMTimeAdd(timeStamp, self->_offset);
54 | }
55 | return timeStamp;
56 | }
57 |
58 | - (CMTime)reconvertTimeStamp:(CMTime)timeStamp
59 | {
60 | if (CMTIME_IS_NUMERIC(self->_scale)) {
61 | timeStamp = SGCMTimeDivide(timeStamp, self->_scale);
62 | }
63 | if (CMTIME_IS_NUMERIC(self->_offset)) {
64 | timeStamp = CMTimeSubtract(timeStamp, self->_offset);
65 | }
66 | return timeStamp;
67 | }
68 |
69 | - (BOOL)isEqualToTimeLayout:(SGTimeLayout *)timeLayout
70 | {
71 | if (!timeLayout) {
72 | return NO;
73 | }
74 | if (CMTimeCompare(timeLayout->_scale, self->_scale) != 0) {
75 | return NO;
76 | }
77 | if (CMTimeCompare(timeLayout->_offset, self->_offset) != 0) {
78 | return NO;
79 | }
80 | return YES;
81 | }
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGData/SGVideoFrame.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGVideoFrame.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/22.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import "SGFrame.h"
10 | #import "SGPLFImage.h"
11 | #import "SGVideoDescriptor.h"
12 |
13 | @interface SGVideoFrame : SGFrame
14 |
15 | /**
16 | *
17 | */
18 | @property (nonatomic, strong, readonly) SGVideoDescriptor *descriptor;
19 |
20 | /**
21 | *
22 | */
23 | - (int *)linesize;
24 |
25 | /**
26 | *
27 | */
28 | - (uint8_t **)data;
29 |
30 | /**
31 | *
32 | */
33 | - (CVPixelBufferRef)pixelBuffer;
34 |
35 | /**
36 | *
37 | */
38 | - (SGPLFImage *)image;
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDecoder/SGAudioDecoder.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioDecoder.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/16.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGDecodable.h"
10 |
11 | @interface SGAudioDecoder : NSObject <SGDecodable>
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDecoder/SGCodecContext.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGCodecContext.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/16.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGCodecDescriptor.h"
11 | #import "SGDecoderOptions.h"
12 | #import "SGPacket.h"
13 | #import "SGFrame.h"
14 |
15 | @interface SGCodecContext : NSObject
16 |
17 | + (instancetype)new NS_UNAVAILABLE;
18 | - (instancetype)init NS_UNAVAILABLE;
19 |
20 | /**
21 | *
22 | */
23 | - (instancetype)initWithTimebase:(AVRational)timebase
24 | codecpar:(AVCodecParameters *)codecpar
25 | frameGenerator:(__kindof SGFrame *(^)(void))frameGenerator;
26 |
27 | /**
28 | *
29 | */
30 | @property (nonatomic, strong) SGDecoderOptions *options;
31 |
32 | /**
33 | *
34 | */
35 | - (BOOL)open;
36 |
37 | /**
38 | *
39 | */
40 | - (void)close;
41 |
42 | /**
43 | *
44 | */
45 | - (void)flush;
46 |
47 | /**
48 | *
49 | */
50 | - (NSArray<__kindof SGFrame *> *)decode:(SGPacket *)packet;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDecoder/SGDecodable.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGDecodable.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/10/22.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGDecoderOptions.h"
11 | #import "SGPacket.h"
12 | #import "SGFrame.h"
13 |
14 | @protocol SGDecodable <NSObject>
15 |
16 | /**
17 | *
18 | */
19 | @property (nonatomic, strong) SGDecoderOptions *options;
20 |
21 | /**
22 | *
23 | */
24 | - (NSArray<__kindof SGFrame *> *)decode:(SGPacket *)packet;
25 |
26 | /**
27 | *
28 | */
29 | - (NSArray<__kindof SGFrame *> *)finish;
30 |
31 | /**
32 | *
33 | */
34 | - (void)flush;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDecoder/SGDecodeContext.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGDecodeContext.h
3 | // KTVMediaKitDemo
4 | //
5 | // Created by Single on 2019/11/18.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGDecoderOptions.h"
11 | #import "SGCapacity.h"
12 | #import "SGPacket.h"
13 | #import "SGFrame.h"
14 |
15 | @interface SGDecodeContext : NSObject
16 |
17 | + (instancetype)new NS_UNAVAILABLE;
18 | - (instancetype)init NS_UNAVAILABLE;
19 |
20 | /**
21 | *
22 | */
23 | - (instancetype)initWithDecoderClass:(Class)decoderClass;
24 |
25 | /**
26 | *
27 | */
28 | @property (nonatomic, copy) SGDecoderOptions *options;
29 |
30 | /**
31 | *
32 | */
33 | @property (nonatomic, readonly) CMTime decodeTimeStamp;
34 |
35 | /**
36 | *
37 | */
38 | - (SGCapacity)capacity;
39 |
40 | /**
41 | *
42 | */
43 | - (void)putPacket:(SGPacket *)packet;
44 |
45 | /**
46 | *
47 | */
48 | - (BOOL)needsPredecode;
49 |
50 | /**
51 | *
52 | */
53 | - (void)predecode:(SGBlock)lock unlock:(SGBlock)unlock;
54 |
55 | /**
56 | *
57 | */
58 | - (NSArray<__kindof SGFrame *> *)decode:(SGBlock)lock unlock:(SGBlock)unlock;
59 |
60 | /**
61 | *
62 | */
63 | - (void)setNeedsFlush;
64 |
65 | /**
66 | *
67 | */
68 | - (void)markAsFinished;
69 |
70 | /**
71 | *
72 | */
73 | - (void)destory;
74 |
75 | @end
76 |
77 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDecoder/SGDecodeLoop.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGDecodeLoop.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/19.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGDecodable.h"
11 | #import "SGCapacity.h"
12 |
13 | @protocol SGDecodeLoopDelegate;
14 |
15 | /**
16 | *
17 | */
18 | typedef NS_ENUM(NSUInteger, SGDecodeLoopState) {
19 | SGDecodeLoopStateNone = 0,
20 | SGDecodeLoopStateDecoding = 1,
21 | SGDecodeLoopStateStalled = 2,
22 | SGDecodeLoopStatePaused = 3,
23 | SGDecodeLoopStateClosed = 4,
24 | };
25 |
26 | @interface SGDecodeLoop : NSObject
27 |
28 | + (instancetype)new NS_UNAVAILABLE;
29 | - (instancetype)init NS_UNAVAILABLE;
30 |
31 | /**
32 | *
33 | */
34 | - (instancetype)initWithDecoderClass:(Class)decoderClass;
35 |
36 | /**
37 | *
38 | */
39 | @property (nonatomic, weak) id<SGDecodeLoopDelegate> delegate;
40 |
41 | /**
42 | *
43 | */
44 | @property (nonatomic, copy) SGDecoderOptions *options;
45 |
46 | /**
47 | *
48 | */
49 | - (SGDecodeLoopState)state;
50 |
51 | /**
52 | *
53 | */
54 | - (BOOL)open;
55 |
56 | /**
57 | *
58 | */
59 | - (BOOL)close;
60 |
61 | /**
62 | *
63 | */
64 | - (BOOL)pause;
65 |
66 | /**
67 | *
68 | */
69 | - (BOOL)resume;
70 |
71 | /**
72 | *
73 | */
74 | - (BOOL)flush;
75 |
76 | /**
77 | *
78 | */
79 | - (BOOL)finish:(NSArray<SGTrack *> *)tracks;
80 |
81 | /**
82 | *
83 | */
84 | - (BOOL)putPacket:(SGPacket *)packet;
85 |
86 | @end
87 |
88 | @protocol SGDecodeLoopDelegate <NSObject>
89 |
90 | /**
91 | *
92 | */
93 | - (void)decodeLoop:(SGDecodeLoop *)decodeLoop didChangeState:(SGDecodeLoopState)state;
94 |
95 | /**
96 | *
97 | */
98 | - (void)decodeLoop:(SGDecodeLoop *)decodeLoop didChangeCapacity:(SGCapacity)capacity;
99 |
100 | /**
101 | *
102 | */
103 | - (void)decodeLoop:(SGDecodeLoop *)decodeLoop didOutputFrames:(NSArray<__kindof SGFrame *> *)frames needsDrop:(BOOL(^)(void))needsDrop;
104 |
105 | @end
106 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDecoder/SGVideoDecoder.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGVideoDecoder.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/16.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGDecodable.h"
10 |
11 | @interface SGVideoDecoder : NSObject <SGDecodable>
12 |
13 | /**
14 | *
15 | */
16 | @property (nonatomic) BOOL outputFromKeyFrame;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDefine/SGMacro.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMacro.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 16/6/29.
6 | // Copyright © 2016年 single. All rights reserved.
7 | //
8 |
9 | #ifndef SGMacro_h
10 | #define SGMacro_h
11 |
12 | #import <Foundation/Foundation.h>
13 |
14 | #define SGWeakify(obj) __weak typeof(obj) weak_obj = obj;
15 | #define SGStrongify(obj) __strong typeof(weak_obj) obj = weak_obj;
16 |
17 | #ifdef DEBUG
18 | #define SGPlayerLog(...) NSLog(__VA_ARGS__)
19 | #else
20 | #define SGPlayerLog(...)
21 | #endif
22 |
23 | #define SGGet0Map(ret, name0, obj) - (ret)name0 {return obj.name0;}
24 | #define SGGet1Map(ret, name0, t0, obj) - (ret)name0:(t0)n0 {return [obj name0:n0];}
25 | #define SGGet00Map(ret, name0, name00, obj) - (ret)name0 {return obj.name00;}
26 | #define SGGet11Map(ret, name0, name00, t0, obj) - (ret)name0:(t0)n0 {return [obj name00:n0];}
27 |
28 | #define SGSet1Map(ret, name0, t0, obj) - (ret)name0:(t0)n0 {[obj name0:n0];}
29 | #define SGSet2Map(ret, name0, t0, name1, t1, obj) - (ret)name0:(t0)n0 name1:(t1)n1 {[obj name0:n0 name1:n1];}
30 | #define SGSet11Map(ret, name0, name00, t0, obj) - (ret)name0:(t0)n0 {[obj name00:n0];}
31 | #define SGSet22Map(ret, name0, name00, t0, name1, name11, t1, obj) - (ret)name0:(t0)n0 name1:(t1)n1 {[obj name00:n0 name11:n1];}
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDefine/SGMapping.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMapping.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/26.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGVideoRenderer.h"
11 | #import "SGMetalViewport.h"
12 | #import "SGFFmpeg.h"
13 |
14 | // SG <-> SGMetal
15 | SGMetalViewportMode SGScaling2Viewport(SGScalingMode mode);
16 | SGScalingMode SGViewport2Scaling(SGMetalViewportMode mode);
17 |
18 | // FF <-> SG
19 | SGMediaType SGMediaTypeFF2SG(enum AVMediaType mediaType);
20 | enum AVMediaType SGMediaTypeSG2FF(SGMediaType mediaType);
21 |
22 | // FF <-> AV
23 | OSType SGPixelFormatFF2AV(enum AVPixelFormat format);
24 | enum AVPixelFormat SGPixelFormatAV2FF(OSType format);
25 |
26 | // FF <-> NS
27 | AVDictionary * SGDictionaryNS2FF(NSDictionary *dictionary);
28 | NSDictionary * SGDictionaryFF2NS(AVDictionary *dictionary);
29 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDemuxer/SGDemuxable.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGDemuxable.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/9/25.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGDemuxerOptions.h"
11 | #import "SGPacket.h"
12 |
13 | @protocol SGDemuxableDelegate;
14 |
15 | @protocol SGDemuxable <NSObject>
16 |
17 | /**
18 | *
19 | */
20 | @property (nonatomic, copy) SGDemuxerOptions *options;
21 |
22 | /**
23 | *
24 | */
25 | @property (nonatomic, weak) id<SGDemuxableDelegate> delegate;
26 |
27 | /**
28 | *
29 | */
30 | @property (nonatomic, copy, readonly) NSArray<SGTrack *> *tracks;
31 |
32 | /**
33 | *
34 | */
35 | @property (nonatomic, copy, readonly) NSArray<SGTrack *> *finishedTracks;
36 |
37 | /**
38 | *
39 | */
40 | @property (nonatomic, copy, readonly) NSDictionary *metadata;
41 |
42 | /**
43 | *
44 | */
45 | @property (nonatomic, readonly) CMTime duration;
46 |
47 | /**
48 | *
49 | */
50 | - (id<SGDemuxable>)sharedDemuxer;
51 |
52 | /**
53 | *
54 | */
55 | - (NSError *)open;
56 |
57 | /**
58 | *
59 | */
60 | - (NSError *)close;
61 |
62 | /**
63 | *
64 | */
65 | - (NSError *)seekable;
66 |
67 | /**
68 | *
69 | */
70 | - (NSError *)seekToTime:(CMTime)time;
71 |
72 | /**
73 | *
74 | */
75 | - (NSError *)seekToTime:(CMTime)time toleranceBefor:(CMTime)toleranceBefor toleranceAfter:(CMTime)toleranceAfter;
76 |
77 | /**
78 | *
79 | */
80 | - (NSError *)nextPacket:(SGPacket **)packet;
81 |
82 | @end
83 |
84 | @protocol SGDemuxableDelegate <NSObject>
85 |
86 | /**
87 | *
88 | */
89 | - (BOOL)demuxableShouldAbortBlockingFunctions:(id<SGDemuxable>)demuxable;
90 |
91 | @end
92 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDemuxer/SGExtractingDemuxer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGExtractingDemuxer.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/14.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGDemuxable.h"
10 |
11 | @interface SGExtractingDemuxer : NSObject <SGDemuxable>
12 |
13 | /**
14 | *
15 | */
16 | + (instancetype)new NS_UNAVAILABLE;
17 | - (instancetype)init NS_UNAVAILABLE;
18 |
19 | /**
20 | *
21 | */
22 | - (instancetype)initWithDemuxable:(id<SGDemuxable>)demuxable index:(NSInteger)index timeRange:(CMTimeRange)timeRange scale:(CMTime)scale;
23 |
24 | /**
25 | *
26 | */
27 | @property (nonatomic, strong, readonly) id<SGDemuxable> demuxable;
28 |
29 | /**
30 | *
31 | */
32 | @property (nonatomic, readonly) NSInteger index;
33 |
34 | /**
35 | *
36 | */
37 | @property (nonatomic, readonly) CMTimeRange timeRange;
38 |
39 | /**
40 | *
41 | */
42 | @property (nonatomic, readonly) CMTime scale;
43 |
44 | /**
45 | *
46 | */
47 | @property (nonatomic) BOOL overgop;
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDemuxer/SGMutilDemuxer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMutilDemuxer.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/16.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGDemuxable.h"
10 |
11 | @interface SGMutilDemuxer : NSObject <SGDemuxable>
12 |
13 | /**
14 | *
15 | */
16 | + (instancetype)new NS_UNAVAILABLE;
17 | - (instancetype)init NS_UNAVAILABLE;
18 |
19 | /**
20 | *
21 | */
22 | - (instancetype)initWithDemuxables:(NSArray<id<SGDemuxable>> *)demuxables;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDemuxer/SGPaddingDemuxer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPaddingDemuxer.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/4.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGDemuxable.h"
10 |
11 | @interface SGPaddingDemuxer : NSObject <SGDemuxable>
12 |
13 | /**
14 | *
15 | */
16 | + (instancetype)new NS_UNAVAILABLE;
17 | - (instancetype)init NS_UNAVAILABLE;
18 |
19 | /**
20 | *
21 | */
22 | - (instancetype)initWithDuration:(CMTime)duration;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDemuxer/SGPaddingDemuxer.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGPaddingDemuxer.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/4.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGPaddingDemuxer.h"
10 | #import "SGPacket+Internal.h"
11 | #import "SGError.h"
12 |
13 | @interface SGPaddingDemuxer ()
14 |
15 | @property (nonatomic, readonly) CMTime lasttime;
16 |
17 | @end
18 |
19 | @implementation SGPaddingDemuxer
20 |
21 | @synthesize tracks = _tracks;
22 | @synthesize options = _options;
23 | @synthesize delegate = _delegate;
24 | @synthesize metadata = _metadata;
25 | @synthesize duration = _duration;
26 | @synthesize finishedTracks = _finishedTracks;
27 |
28 | - (instancetype)initWithDuration:(CMTime)duration
29 | {
30 | if (self = [super init]) {
31 | self->_duration = duration;
32 | [self seekToTime:kCMTimeZero];
33 | }
34 | return self;
35 | }
36 |
37 | #pragma mark - Control
38 |
39 | - (id<SGDemuxable>)sharedDemuxer
40 | {
41 | return nil;
42 | }
43 |
44 | - (NSError *)open
45 | {
46 | return nil;
47 | }
48 |
49 | - (NSError *)close
50 | {
51 | return nil;
52 | }
53 |
54 | - (NSError *)seekable
55 | {
56 | return nil;
57 | }
58 |
59 | - (NSError *)seekToTime:(CMTime)time
60 | {
61 | return [self seekToTime:time toleranceBefor:kCMTimeInvalid toleranceAfter:kCMTimeInvalid];
62 | }
63 |
64 | - (NSError *)seekToTime:(CMTime)time toleranceBefor:(CMTime)toleranceBefor toleranceAfter:(CMTime)toleranceAfter
65 | {
66 | if (!CMTIME_IS_NUMERIC(time)) {
67 | return SGCreateError(SGErrorCodeInvlidTime, SGActionCodeFormatSeekFrame);
68 | }
69 | time = CMTimeMaximum(time, kCMTimeZero);
70 | time = CMTimeMinimum(time, self->_duration);
71 | self->_lasttime = time;
72 | return nil;
73 | }
74 |
75 | - (NSError *)nextPacket:(SGPacket **)packet
76 | {
77 | if (CMTimeCompare(self->_lasttime, self->_duration) >= 0) {
78 | return SGCreateError(SGErrorCodeDemuxerEndOfFile, SGActionCodeFormatReadFrame);
79 | }
80 | CMTime timeStamp = self->_lasttime;
81 | CMTime duration = CMTimeSubtract(self->_duration, self->_lasttime);
82 | SGPacket *pkt = [SGPacket packet];
83 | pkt.flags |= SGDataFlagPadding;
84 | pkt.core->size = 1;
85 | pkt.core->pts = av_rescale(AV_TIME_BASE, timeStamp.value, timeStamp.timescale);
86 | pkt.core->dts = av_rescale(AV_TIME_BASE, timeStamp.value, timeStamp.timescale);
87 | pkt.core->duration = av_rescale(AV_TIME_BASE, duration.value, duration.timescale);
88 | SGCodecDescriptor *cd = [[SGCodecDescriptor alloc] init];
89 | cd.timebase = AV_TIME_BASE_Q;
90 | [pkt setCodecDescriptor:cd];
91 | [pkt fill];
92 | *packet = pkt;
93 | self->_lasttime = self->_duration;
94 | return nil;
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDemuxer/SGTrackDemuxer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGTrackDemuxer.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/14.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGDemuxable.h"
10 | #import "SGMutableTrack.h"
11 |
12 | @interface SGTrackDemuxer : NSObject <SGDemuxable>
13 |
14 | /**
15 | *
16 | */
17 | + (instancetype)new NS_UNAVAILABLE;
18 | - (instancetype)init NS_UNAVAILABLE;
19 |
20 | /**
21 | *
22 | */
23 | - (instancetype)initWithTrack:(SGMutableTrack *)track;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDemuxer/SGURLDemuxer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGURLDemuxer.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/13.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGDemuxable.h"
10 |
11 | @interface SGURLDemuxer : NSObject <SGDemuxable>
12 |
13 | + (instancetype)new NS_UNAVAILABLE;
14 | - (instancetype)init NS_UNAVAILABLE;
15 |
16 | /*!
17 | @method initWithURL:
18 | @abstract
19 | Initializes an SGURLDemuxer with an NSURL.
20 | */
21 | - (instancetype)initWithURL:(NSURL *)URL;
22 |
23 | /*!
24 | @property URL
25 | @abstract
26 | Indicates the URL of the demuxer.
27 | */
28 | @property (nonatomic, copy, readonly) NSURL *URL;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDescription/SGAudioDescriptor.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioDescriptor.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/28.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 |
11 | @interface SGAudioDescriptor : NSObject <NSCopying>
12 |
13 | /*!
14 | @property format
15 | @abstract
16 | Indicates the audio format.
17 |
18 | @discussion
19 | The value corresponds to AVSampleFormat.
20 | */
21 | @property (nonatomic) int format;
22 |
23 | /*!
24 | @property sampleRate
25 | @abstract
26 | Indicates the sample rate.
27 | */
28 | @property (nonatomic) int sampleRate;
29 |
30 | /*!
31 | @property numberOfChannels
32 | @abstract
33 | Indicates the channel count.
34 | */
35 | @property (nonatomic) int numberOfChannels;
36 |
37 | /*!
38 | @method isPlanar
39 | @abstract
40 | Get whether the sample format is planar.
41 | */
42 | - (BOOL)isPlanar;
43 |
44 | /*!
45 | @method bytesPerSample
46 | @abstract
47 | Get the bytes per sample.
48 | */
49 | - (int)bytesPerSample;
50 |
51 | /*!
52 | @method numberOfPlanes
53 | @abstract
54 | Get the number of planes.
55 | */
56 | - (int)numberOfPlanes;
57 |
58 | /*!
59 | @method linesize:
60 | @abstract
61 | Get the linesize of the number of samples.
62 | */
63 | - (int)linesize:(int)numberOfSamples;
64 |
65 | /*!
66 | @method isEqualToDescriptor:
67 | @abstract
68 | Check if the descriptor is equal to another.
69 | */
70 | - (BOOL)isEqualToDescriptor:(SGAudioDescriptor *)descriptor;
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDescription/SGAudioDescriptor.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioDescriptor.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/28.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGAudioDescriptor.h"
10 | #import "SGDescriptor+Internal.h"
11 | #import "SGFFmpeg.h"
12 |
13 | @implementation SGAudioDescriptor
14 |
15 | - (id)copyWithZone:(NSZone *)zone
16 | {
17 | SGAudioDescriptor *obj = [[SGAudioDescriptor alloc] init];
18 | obj->_format = self->_format;
19 | obj->_sampleRate = self->_sampleRate;
20 | obj->_numberOfChannels = self->_numberOfChannels;
21 | obj->_channelLayout = self->_channelLayout;
22 | return obj;
23 | }
24 |
25 | - (instancetype)init
26 | {
27 | if (self = [super init]) {
28 | self->_format = AV_SAMPLE_FMT_FLTP;
29 | self->_sampleRate = 44100;
30 | self->_numberOfChannels = 2;
31 | av_channel_layout_default(&self->_channelLayout, 2);
32 | }
33 | return self;
34 | }
35 |
36 | - (instancetype)initWithFrame:(AVFrame *)frame
37 | {
38 | if (self = [super init]) {
39 | self->_format = frame->format;
40 | self->_sampleRate = frame->sample_rate;
41 | self->_numberOfChannels = frame->ch_layout.nb_channels;
42 | self->_channelLayout = frame->ch_layout;
43 | }
44 | return self;
45 | }
46 |
47 | - (BOOL)isPlanar
48 | {
49 | return av_sample_fmt_is_planar(self->_format);
50 | }
51 |
52 | - (int)bytesPerSample
53 | {
54 | return av_get_bytes_per_sample(self->_format);
55 | }
56 |
57 | - (int)numberOfPlanes
58 | {
59 | return av_sample_fmt_is_planar(self->_format) ? self->_numberOfChannels : 1;
60 | }
61 |
62 | - (int)linesize:(int)numberOfSamples
63 | {
64 | int linesize = av_get_bytes_per_sample(self->_format) * numberOfSamples;
65 | linesize *= av_sample_fmt_is_planar(self->_format) ? 1 : self->_numberOfChannels;
66 | return linesize;
67 | }
68 |
69 | - (BOOL)isEqualToDescriptor:(SGAudioDescriptor *)descriptor
70 | {
71 | if (!descriptor) {
72 | return NO;
73 | }
74 | return
75 | self->_format == descriptor->_format &&
76 | self->_sampleRate == descriptor->_sampleRate &&
77 | self->_numberOfChannels == descriptor->_numberOfChannels &&
78 | (av_channel_layout_compare(&self->_channelLayout, &descriptor->_channelLayout) == 0);
79 | }
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDescription/SGCodecDescriptor.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGCodecDescriptor.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/15.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGTimeLayout.h"
11 | #import "SGFFmpeg.h"
12 | #import "SGTrack.h"
13 |
14 | @interface SGCodecDescriptor : NSObject <NSCopying>
15 |
16 | /**
17 | *
18 | */
19 | @property (nonatomic) AVRational timebase;
20 |
21 | /**
22 | *
23 | */
24 | @property (nonatomic) AVCodecParameters *codecpar;
25 |
26 | /**
27 | *
28 | */
29 | @property (nonatomic, strong) SGTrack *track;
30 |
31 | /**
32 | *
33 | */
34 | @property (nonatomic, strong) NSDictionary *metadata;
35 |
36 | /**
37 | *
38 | */
39 | @property (nonatomic, readonly) CMTimeRange timeRange;
40 |
41 | /**
42 | *
43 | */
44 | @property (nonatomic, readonly) CMTime scale;
45 |
46 | /**
47 | *
48 | */
49 | - (CMTime)convertTimeStamp:(CMTime)timeStamp;
50 |
51 | /**
52 | *
53 | */
54 | - (CMTime)convertDuration:(CMTime)duration;
55 |
56 | /**
57 | *
58 | */
59 | - (void)appendTimeRange:(CMTimeRange)timeRange;
60 |
61 | /**
62 | *
63 | */
64 | - (void)appendTimeLayout:(SGTimeLayout *)timeLayout;
65 |
66 | /**
67 | *
68 | */
69 | - (void)fillToDescriptor:(SGCodecDescriptor *)descriptor;
70 |
71 | /**
72 | *
73 | */
74 | - (BOOL)isEqualToDescriptor:(SGCodecDescriptor *)descriptor;
75 |
76 | /**
77 | *
78 | */
79 | - (BOOL)isEqualCodecContextToDescriptor:(SGCodecDescriptor *)descriptor;
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDescription/SGDescriptor+Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPacket+Internal.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/23.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGPacket.h"
10 | #import "SGFFmpeg.h"
11 | #import "SGAudioDescriptor.h"
12 | #import "SGVideoDescriptor.h"
13 |
14 | @interface SGAudioDescriptor ()
15 |
16 | - (instancetype)initWithFrame:(AVFrame *)frame;
17 |
18 | /*!
19 | @property channelLayout
20 | @abstract
21 | Indicates the channel layout.
22 | */
23 | @property (nonatomic) AVChannelLayout channelLayout;
24 |
25 | @end
26 |
27 | @interface SGVideoDescriptor ()
28 |
29 | - (instancetype)initWithFrame:(AVFrame *)frame;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGDescription/SGVideoDescriptor.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGVideoDescriptor.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/12/11.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGDefines.h"
11 |
12 | @interface SGVideoDescriptor : NSObject <NSCopying>
13 |
14 | /*!
15 | @property format
16 | @abstract
17 | Indicates the vdieo format.
18 |
19 | @discussion
20 | The value corresponds to AVPixelFormat.
21 | */
22 | @property (nonatomic) int format;
23 |
24 | /*!
25 | @property cv_format
26 | @abstract
27 | Indicates the vdieo format.
28 |
29 | @discussion
30 | The value corresponds to kCVPixelFormatType_XXX.
31 | */
32 | @property (nonatomic) OSType cv_format;
33 |
34 | /*!
35 | @property width
36 | @abstract
37 | Indicates the width.
38 | */
39 | @property (nonatomic) int width;
40 |
41 | /*!
42 | @property height
43 | @abstract
44 | Indicates the height.
45 | */
46 | @property (nonatomic) int height;
47 |
48 | /*!
49 | @property sampleAspectRatio
50 | @abstract
51 | Indicates the sample aspect ratio, 0/1 if unknown/unspecified.
52 | */
53 | @property (nonatomic) SGRational sampleAspectRatio;
54 |
55 | /*!
56 | @property frameSize
57 | @abstract
58 | Indicates the pixel buffer frame size.
59 | */
60 | @property (nonatomic, readonly) SGRational frameSize;
61 |
62 | /*!
63 | @property presentationSize
64 | @abstract
65 | Indicates the best presentation size.
66 | */
67 | @property (nonatomic, readonly) SGRational presentationSize;
68 |
69 | /*!
70 | @method numberOfPlanes
71 | @abstract
72 | Get the number of planes.
73 | */
74 | - (int)numberOfPlanes;
75 |
76 | /*!
77 | @method isEqualToDescriptor:
78 | @abstract
79 | Check if the descriptor is equal to another.
80 | */
81 | - (BOOL)isEqualToDescriptor:(SGVideoDescriptor *)descriptor;
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGFFmpeg/SGFFmpeg.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGFFmpeg.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/8/2.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #pragma clang diagnostic push
11 | #pragma clang diagnostic ignored "-Wdocumentation"
12 | #import "avformat.h"
13 | #import "imgutils.h"
14 | #import "swresample.h"
15 | #import "swscale.h"
16 | #import "avcodec.h"
17 | #pragma clang diagnostic pop
18 |
19 | void SGFFmpegSetupIfNeeded(void);
20 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGFFmpeg/SGFFmpeg.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGFFmpeg.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/8/2.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGFFmpeg.h"
10 |
11 | static void SGFFmpegLogCallback(void * context, int level, const char * format, va_list args)
12 | {
13 | // NSString * message = [[NSString alloc] initWithFormat:[NSString stringWithUTF8String:format] arguments:args];
14 | // NSLog(@"SGFFLog : %@", message);
15 | }
16 |
17 | void SGFFmpegSetupIfNeeded(void)
18 | {
19 | static dispatch_once_t onceToken;
20 | dispatch_once(&onceToken, ^{
21 | av_log_set_callback(SGFFmpegLogCallback);
22 | avformat_network_init();
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetal.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #ifndef SGMetal_h
10 | #define SGMetal_h
11 |
12 | #import <Metal/Metal.h>
13 | #import <MetalKit/MetalKit.h>
14 |
15 | #import "SGMetalTypes.h"
16 | #import "SGMetalRenderer.h"
17 | #import "SGMetalViewport.h"
18 | #import "SGMetalProjection.h"
19 | #import "SGMetalTextureLoader.h"
20 |
21 | #import "SGMetalModel.h"
22 | #import "SGMetalPlaneModel.h"
23 | #import "SGMetalSphereModel.h"
24 |
25 | #import "SGMetalRenderPipeline.h"
26 | #import "SGMetalYUVRenderPipeline.h"
27 | #import "SGMetalNV12RenderPipeline.h"
28 | #import "SGMetalBGRARenderPipeline.h"
29 | #import "SGMetalRenderPipelinePool.h"
30 |
31 | #endif /* SGMetal_h */
32 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalBGRARenderPipeline.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalBGRARenderPipeline.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalRenderPipeline.h"
10 |
11 | @interface SGMetalBGRARenderPipeline : SGMetalRenderPipeline
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalBGRARenderPipeline.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalBGRARenderPipeline.m
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalBGRARenderPipeline.h"
10 |
11 | @implementation SGMetalBGRARenderPipeline
12 |
13 | - (instancetype)initWithDevice:(id<MTLDevice>)device library:(id<MTLLibrary>)library
14 | {
15 | if (self = [super initWithDevice:device library:library]) {
16 | self.descriptor = [[MTLRenderPipelineDescriptor alloc] init];
17 | self.descriptor.vertexFunction = [self.library newFunctionWithName:@"vertexShader"];
18 | self.descriptor.fragmentFunction = [self.library newFunctionWithName:@"fragmentShaderBGRA"];
19 | self.descriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
20 | self.state = [self.device newRenderPipelineStateWithDescriptor:self.descriptor error:nil];
21 | }
22 | return self;
23 | }
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalModel.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/24.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import <Metal/Metal.h>
10 |
11 | @interface SGMetalModel : NSObject
12 |
13 | - (instancetype)initWithDevice:(id<MTLDevice>)device;
14 |
15 | @property (nonatomic) NSUInteger indexCount;
16 | @property (nonatomic) MTLIndexType indexType;
17 | @property (nonatomic) MTLPrimitiveType primitiveType;
18 | @property (nonatomic, strong) id<MTLDevice> device;
19 | @property (nonatomic, strong) id<MTLBuffer> indexBuffer;
20 | @property (nonatomic, strong) id<MTLBuffer> vertexBuffer;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalModel.m
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/24.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalModel.h"
10 |
11 | @implementation SGMetalModel
12 |
13 | - (instancetype)initWithDevice:(id<MTLDevice>)device
14 | {
15 | if (self = [super init]) {
16 | self.device = device;
17 | }
18 | return self;
19 | }
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalNV12RenderPipeline.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalNV12RenderPipeline.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalRenderPipeline.h"
10 |
11 | @interface SGMetalNV12RenderPipeline : SGMetalRenderPipeline
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalNV12RenderPipeline.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalNV12RenderPipeline.m
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalNV12RenderPipeline.h"
10 |
11 | @implementation SGMetalNV12RenderPipeline
12 |
13 | - (instancetype)initWithDevice:(id<MTLDevice>)device library:(id<MTLLibrary>)library
14 | {
15 | if (self = [super initWithDevice:device library:library]) {
16 | self.descriptor = [[MTLRenderPipelineDescriptor alloc] init];
17 | self.descriptor.vertexFunction = [self.library newFunctionWithName:@"vertexShader"];
18 | self.descriptor.fragmentFunction = [self.library newFunctionWithName:@"fragmentShaderNV12"];
19 | self.descriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
20 | self.state = [self.device newRenderPipelineStateWithDescriptor:self.descriptor error:nil];
21 | }
22 | return self;
23 | }
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalPlaneModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalPlaneModel.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/25.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalModel.h"
10 |
11 | @interface SGMetalPlaneModel : SGMetalModel
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalPlaneModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalPlaneModel.m
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/25.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalPlaneModel.h"
10 | #import "SGMetalTypes.h"
11 |
12 | @implementation SGMetalPlaneModel
13 |
14 | static const UInt32 indices[] = {
15 | 0, 1, 3, 0, 3, 2,
16 | };
17 |
18 | static const SGMetalVertex vertices[] = {
19 | { { -1.0, -1.0, 0.0, 1.0 }, { 0.0, 1.0 } },
20 | { { -1.0, 1.0, 0.0, 1.0 }, { 0.0, 0.0 } },
21 | { { 1.0, -1.0, 0.0, 1.0 }, { 1.0, 1.0 } },
22 | { { 1.0, 1.0, 0.0, 1.0 }, { 1.0, 0.0 } },
23 | };
24 |
25 | - (instancetype)initWithDevice:(id<MTLDevice>)device
26 | {
27 | if (self = [super initWithDevice:device]) {
28 | self.indexCount = 6;
29 | self.indexType = MTLIndexTypeUInt32;
30 | self.primitiveType = MTLPrimitiveTypeTriangle;
31 | self.indexBuffer = [self.device newBufferWithBytes:indices length:sizeof(indices) options:MTLResourceStorageModeShared];
32 | self.vertexBuffer = [self.device newBufferWithBytes:vertices length:sizeof(vertices) options:MTLResourceStorageModeShared];
33 | }
34 | return self;
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalProjection.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalProjection.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/28.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import <Metal/Metal.h>
10 | #import <GLKit/GLKit.h>
11 |
12 | @interface SGMetalProjection : NSObject
13 |
14 | - (instancetype)initWithDevice:(id<MTLDevice>)device;
15 |
16 | @property (nonatomic) GLKMatrix4 matrix;
17 | @property (nonatomic, strong) id<MTLDevice> device;
18 | @property (nonatomic, strong) id<MTLBuffer> matrixBuffer;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalProjection.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalProjection.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/28.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalProjection.h"
10 | #import "SGMetalTypes.h"
11 |
12 | @implementation SGMetalProjection
13 |
14 | - (instancetype)initWithDevice:(id<MTLDevice>)device
15 | {
16 | if (self = [super init]) {
17 | self.device = device;
18 | self.matrixBuffer = [device newBufferWithLength:sizeof(SGMetalMatrix) options:MTLResourceStorageModeShared];
19 | }
20 | return self;
21 | }
22 |
23 | - (void)setMatrix:(GLKMatrix4)matrix
24 | {
25 | self->_matrix = matrix;
26 | ((SGMetalMatrix *)self.matrixBuffer.contents)->mvp = SGMatrixFloat4x4FromGLKMatrix4(matrix);
27 | }
28 |
29 | static matrix_float4x4 SGMatrixFloat4x4FromGLKMatrix4(GLKMatrix4 matrix)
30 | {
31 | return (matrix_float4x4){{
32 | {matrix.m00, matrix.m01, matrix.m02, matrix.m03},
33 | {matrix.m10, matrix.m11, matrix.m12, matrix.m13},
34 | {matrix.m20, matrix.m21, matrix.m22, matrix.m23},
35 | {matrix.m30, matrix.m31, matrix.m32, matrix.m33}}};
36 | }
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalRenderPipeline.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalRenderPipeline.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import <Metal/Metal.h>
10 |
11 | @interface SGMetalRenderPipeline : NSObject
12 |
13 | - (instancetype)initWithDevice:(id<MTLDevice>)device library:(id<MTLLibrary>)library;
14 |
15 | @property (nonatomic, strong) id<MTLDevice> device;
16 | @property (nonatomic, strong) id<MTLLibrary> library;
17 | @property (nonatomic, strong) id<MTLRenderPipelineState> state;
18 | @property (nonatomic, strong) MTLRenderPipelineDescriptor *descriptor;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalRenderPipeline.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalRenderPipeline.m
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalRenderPipeline.h"
10 |
11 | @implementation SGMetalRenderPipeline
12 |
13 | - (instancetype)initWithDevice:(id<MTLDevice>)device library:(id<MTLLibrary>)library
14 | {
15 | if (self = [super init]) {
16 | self.device = device;
17 | self.library = library;
18 | }
19 | return self;
20 | }
21 |
22 | @end
23 |
24 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalRenderPipelinePool.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalRenderPipelinePool.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGMetalRenderPipeline.h"
11 | #import <CoreVideo/CoreVideo.h>
12 |
13 | @interface SGMetalRenderPipelinePool : NSObject
14 |
15 | - (instancetype)initWithDevice:(id<MTLDevice>)device;
16 |
17 | - (SGMetalRenderPipeline *)pipelineWithCVPixelFormat:(OSType)pixpelFormat;
18 | - (SGMetalRenderPipeline *)pipelineWithCVPixelBuffer:(CVPixelBufferRef)pixelBuffer;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalRenderPipelinePool.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalRenderPipelinePool.m
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalRenderPipelinePool.h"
10 | #import "SGMetalYUVRenderPipeline.h"
11 | #import "SGMetalNV12RenderPipeline.h"
12 | #import "SGMetalBGRARenderPipeline.h"
13 |
14 | #import "SGPLFTargets.h"
15 | #if SGPLATFORM_TARGET_OS_IPHONE
16 | #import "SGMetalShader_iOS.h"
17 | #elif SGPLATFORM_TARGET_OS_TV
18 | #import "SGMetalShader_tvOS.h"
19 | #elif SGPLATFORM_TARGET_OS_MAC
20 | #import "SGMetalShader_macOS.h"
21 | #endif
22 |
23 | @interface SGMetalRenderPipelinePool ()
24 |
25 | @property (nonatomic, strong) id<MTLDevice> device;
26 | @property (nonatomic, strong) id<MTLLibrary> library;
27 | @property (nonatomic, strong) SGMetalRenderPipeline *yuv;
28 | @property (nonatomic, strong) SGMetalRenderPipeline *nv12;
29 | @property (nonatomic, strong) SGMetalRenderPipeline *bgra;
30 |
31 | @end
32 |
33 | @implementation SGMetalRenderPipelinePool
34 |
35 | - (instancetype)initWithDevice:(id<MTLDevice>)device
36 | {
37 | if (self = [super init]) {
38 | self.device = device;
39 | self.library = [device newLibraryWithData:dispatch_data_create(metallib, sizeof(metallib), dispatch_get_global_queue(0, 0), ^{}) error:NULL];
40 | }
41 | return self;
42 | }
43 |
44 | - (SGMetalRenderPipeline *)pipelineWithCVPixelFormat:(OSType)pixpelFormat
45 | {
46 | if (pixpelFormat == kCVPixelFormatType_420YpCbCr8Planar) {
47 | return self.yuv;
48 | } else if (pixpelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) {
49 | return self.nv12;
50 | } else if (pixpelFormat == kCVPixelFormatType_32BGRA) {
51 | return self.bgra;
52 | }
53 | return nil;
54 | }
55 |
56 | - (SGMetalRenderPipeline *)pipelineWithCVPixelBuffer:(CVPixelBufferRef)pixelBuffer
57 | {
58 | return [self pipelineWithCVPixelFormat:CVPixelBufferGetPixelFormatType(pixelBuffer)];
59 | }
60 |
61 | - (SGMetalRenderPipeline *)yuv
62 | {
63 | if (_yuv == nil) {
64 | _yuv = [[SGMetalYUVRenderPipeline alloc] initWithDevice:self.device library:self.library];
65 | }
66 | return _yuv;
67 | }
68 |
69 | - (SGMetalRenderPipeline *)nv12
70 | {
71 | if (_nv12 == nil) {
72 | _nv12 = [[SGMetalNV12RenderPipeline alloc] initWithDevice:self.device library:self.library];
73 | }
74 | return _nv12;
75 | }
76 |
77 | - (SGMetalRenderPipeline *)bgra
78 | {
79 | if (_bgra == nil) {
80 | _bgra = [[SGMetalBGRARenderPipeline alloc] initWithDevice:self.device library:self.library];
81 | }
82 | return _bgra;
83 | }
84 |
85 | @end
86 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalRenderer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalRenderer.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/24.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import <simd/simd.h>
10 | #import <Metal/Metal.h>
11 | #import "SGMetalModel.h"
12 | #import "SGMetalProjection.h"
13 | #import "SGMetalRenderPipeline.h"
14 |
15 | @interface SGMetalRenderer : NSObject
16 |
17 | - (instancetype)initWithDevice:(id<MTLDevice>)device;
18 |
19 | - (id<MTLCommandBuffer>)drawModel:(SGMetalModel *)model
20 | viewports:(MTLViewport[])viewports
21 | pipeline:(SGMetalRenderPipeline *)pipeline
22 | projections:(NSArray<SGMetalProjection *> *)projections
23 | inputTextures:(NSArray<id<MTLTexture>> *)inputTextures
24 | outputTexture:(id<MTLTexture>)outputTexture;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalRenderer.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalRenderer.m
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/24.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalRenderer.h"
10 | #import "SGMetalTypes.h"
11 |
12 | @interface SGMetalRenderer ()
13 |
14 | @property (nonatomic, strong) id<MTLDevice> device;
15 | @property (nonatomic, strong) id<MTLCommandQueue> commandQueue;
16 | @property (nonatomic, strong) MTLRenderPassDescriptor *renderPassDescriptor;
17 |
18 | @end
19 |
20 | @implementation SGMetalRenderer
21 |
22 | - (instancetype)initWithDevice:(id<MTLDevice>)device
23 | {
24 | if (self = [super init]) {
25 | self.device = device;
26 | self.commandQueue = [self.device newCommandQueue];
27 | self.renderPassDescriptor = [[MTLRenderPassDescriptor alloc] init];
28 | self.renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 1);
29 | self.renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
30 | self.renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
31 | }
32 | return self;
33 | }
34 |
35 | - (id<MTLCommandBuffer>)drawModel:(SGMetalModel *)model
36 | viewports:(MTLViewport[])viewports
37 | pipeline:(SGMetalRenderPipeline *)pipeline
38 | projections:(NSArray<SGMetalProjection *> *)projections
39 | inputTextures:(NSArray<id<MTLTexture>> *)inputTextures
40 | outputTexture:(id<MTLTexture>)outputTexture
41 | {
42 | self.renderPassDescriptor.colorAttachments[0].texture = outputTexture;
43 | id<MTLCommandBuffer> commandBuffer = [self.commandQueue commandBuffer];
44 | id<MTLRenderCommandEncoder> encoder = [commandBuffer renderCommandEncoderWithDescriptor:self.renderPassDescriptor];
45 | [encoder setCullMode:MTLCullModeNone];
46 | [encoder setRenderPipelineState:pipeline.state];
47 | [encoder setVertexBuffer:model.vertexBuffer offset:0 atIndex:0];
48 | for (NSUInteger i = 0; i < inputTextures.count; i++) {
49 | [encoder setFragmentTexture:inputTextures[i] atIndex:i];
50 | }
51 | for (NSUInteger i = 0; i < projections.count; i++) {
52 | [encoder setViewport:viewports[i]];
53 | [encoder setVertexBuffer:projections[i].matrixBuffer offset:0 atIndex:1];
54 | [encoder drawIndexedPrimitives:model.primitiveType
55 | indexCount:model.indexCount
56 | indexType:model.indexType
57 | indexBuffer:model.indexBuffer
58 | indexBufferOffset:0];
59 | }
60 | [encoder endEncoding];
61 | return commandBuffer;
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalSphereModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalSphereModel.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/25.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalModel.h"
10 |
11 | @interface SGMetalSphereModel : SGMetalModel
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalSphereModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalSphereModel.m
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/25.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalSphereModel.h"
10 | #import "SGMetalTypes.h"
11 |
12 | @implementation SGMetalSphereModel
13 |
14 | static int const slicesCount = 200;
15 | static int const parallelsCount = slicesCount / 2;
16 | static int const indicesCount = slicesCount * parallelsCount * 6;
17 | static int const verticesCount = (slicesCount + 1) * (parallelsCount + 1);
18 |
19 | static UInt32 indices [indicesCount];
20 | static SGMetalVertex vertices[verticesCount];
21 |
22 | - (instancetype)initWithDevice:(id<MTLDevice>)device
23 | {
24 | if (self = [super initWithDevice:device]) {
25 | static dispatch_once_t onceToken;
26 | dispatch_once(&onceToken, ^{
27 | int runCount = 0;
28 | float const radius = 1.0f;
29 | float const step = (2.0f * M_PI) / (float)slicesCount;
30 | for (int i = 0; i < parallelsCount + 1; i++) {
31 | for (int j = 0; j < slicesCount + 1; j++) {
32 | SGMetalVertex vertex;
33 | vertex.position[0] = radius * sinf(step * (float)i) * cosf(step * (float)j);
34 | vertex.position[1] = radius * cosf(step * (float)i);
35 | vertex.position[2] = radius * sinf(step * (float)i) * sinf(step * (float)j);
36 | vertex.position[3] = 1.0;
37 | vertex.texCoord[0] = (float)j / (float)slicesCount;
38 | vertex.texCoord[1] = (float)i / (float)parallelsCount;
39 | vertices[i * (slicesCount + 1) + j] = vertex;
40 | if (i < parallelsCount && j < slicesCount) {
41 | indices[runCount++] = i * (slicesCount + 1) + j;
42 | indices[runCount++] = (i + 1) * (slicesCount + 1) + j;
43 | indices[runCount++] = (i + 1) * (slicesCount + 1) + (j + 1);
44 | indices[runCount++] = i * (slicesCount + 1) + j;
45 | indices[runCount++] = (i + 1) * (slicesCount + 1) + (j + 1);
46 | indices[runCount++] = i * (slicesCount + 1) + (j + 1);
47 | }
48 | }
49 | }
50 | });
51 | self.indexCount = indicesCount;
52 | self.indexType = MTLIndexTypeUInt32;
53 | self.primitiveType = MTLPrimitiveTypeTriangle;
54 | self.indexBuffer = [self.device newBufferWithBytes:indices length:sizeof(indices) options:MTLResourceStorageModeShared];
55 | self.vertexBuffer = [self.device newBufferWithBytes:vertices length:sizeof(vertices) options:MTLResourceStorageModeShared];
56 | }
57 | return self;
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalTextureLoader.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalTextureLoader.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import <Metal/Metal.h>
10 | #import <CoreVideo/CoreVideo.h>
11 |
12 | @interface SGMetalTextureLoader : NSObject
13 |
14 | - (instancetype)initWithDevice:(id<MTLDevice>)device;
15 |
16 | - (NSArray<id<MTLTexture>> *)texturesWithCVPixelBuffer:(CVPixelBufferRef)pixelBuffer;
17 |
18 | - (NSArray<id<MTLTexture>> *)texturesWithCVPixelFormat:(OSType)pixelFormat
19 | width:(NSUInteger)width
20 | height:(NSUInteger)height
21 | bytes:(void **)bytes
22 | bytesPerRow:(int *)bytesPerRow;
23 |
24 | - (id<MTLTexture>)textureWithPixelFormat:(MTLPixelFormat)pixelFormat
25 | width:(NSUInteger)width
26 | height:(NSUInteger)height
27 | bytes:(void *)bytes
28 | bytesPerRow:(NSUInteger)bytesPerRow;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalTypes.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalTypes.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/21.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #ifndef SGMetalTypes_h
10 | #define SGMetalTypes_h
11 |
12 | #include <simd/simd.h>
13 |
14 | typedef struct {
15 | vector_float4 position;
16 | vector_float2 texCoord;
17 | } SGMetalVertex;
18 |
19 | typedef struct {
20 | matrix_float4x4 mvp;
21 | } SGMetalMatrix;
22 |
23 | #endif /* SGMetalTypes_h */
24 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalViewport.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalViewport.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/27.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import <Metal/Metal.h>
10 |
11 | typedef NS_ENUM(NSUInteger, SGMetalViewportMode) {
12 | SGMetalViewportModeResize = 0,
13 | SGMetalViewportModeResizeAspect = 1,
14 | SGMetalViewportModeResizeAspectFill = 2,
15 | };
16 |
17 | @interface SGMetalViewport : NSObject
18 |
19 | + (MTLViewport)viewportWithLayerSize:(MTLSize)layerSize;
20 | + (MTLViewport)viewportWithLayerSizeForLeft:(MTLSize)layerSize;
21 | + (MTLViewport)viewportWithLayerSizeForRight:(MTLSize)layerSize;
22 | + (MTLViewport)viewportWithLayerSize:(MTLSize)layerSize textureSize:(MTLSize)textureSize mode:(SGMetalViewportMode)mode;
23 |
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalYUVRenderPipeline.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalYUVRenderPipeline.h
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalRenderPipeline.h"
10 |
11 | @interface SGMetalYUVRenderPipeline : SGMetalRenderPipeline
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGMetal/SGMetalYUVRenderPipeline.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGMetalYUVRenderPipeline.m
3 | // MetalTest
4 | //
5 | // Created by Single on 2019/6/26.
6 | // Copyright © 2019 Single. All rights reserved.
7 | //
8 |
9 | #import "SGMetalYUVRenderPipeline.h"
10 |
11 | @implementation SGMetalYUVRenderPipeline
12 |
13 | - (instancetype)initWithDevice:(id<MTLDevice>)device library:(id<MTLLibrary>)library
14 | {
15 | if (self = [super initWithDevice:device library:library]) {
16 | self.descriptor = [[MTLRenderPipelineDescriptor alloc] init];
17 | self.descriptor.vertexFunction = [self.library newFunctionWithName:@"vertexShader"];
18 | self.descriptor.fragmentFunction = [self.library newFunctionWithName:@"fragmentShaderYUV"];
19 | self.descriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
20 | self.state = [self.device newRenderPipelineStateWithDescriptor:self.descriptor error:nil];
21 | }
22 | return self;
23 | }
24 |
25 | @end
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGOption/SGDecoderOptions.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGDecoderOptions.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/14.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGAudioDescriptor.h"
11 | #import "SGTime.h"
12 |
13 | @interface SGDecoderOptions : NSObject <NSCopying>
14 |
15 | /*!
16 | @property options
17 | @abstract
18 | The options for avformat_open_input.
19 | Default is nil.
20 | */
21 | @property (nonatomic, copy) NSDictionary *options;
22 |
23 | /*!
24 | @property threadsAuto
25 | @abstract
26 | The option for avformat_open_input.
27 | Default is YES.
28 | */
29 | @property (nonatomic) BOOL threadsAuto;
30 |
31 | /*!
32 | @property refcountedFrames
33 | @abstract
34 | The option for avformat_open_input.
35 | Default is YES.
36 | */
37 | @property (nonatomic) BOOL refcountedFrames;
38 |
39 | /*!
40 | @property hardwareDecodeH264
41 | @abstract
42 | Indicates whether hardware decoding is enabled for H264.
43 | Default is YES.
44 | */
45 | @property (nonatomic) BOOL hardwareDecodeH264;
46 |
47 | /*!
48 | @property hardwareDecodeH265
49 | @abstract
50 | Indicates whether hardware decoding is enabled for H265.
51 | Default is YES.
52 | */
53 | @property (nonatomic) BOOL hardwareDecodeH265;
54 |
55 | /*!
56 | @property preferredPixelFormat
57 | @abstract
58 | Indicates the default hardware decoding output format.
59 | Default is kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange.
60 | */
61 | @property (nonatomic) OSType preferredCVPixelFormat;
62 |
63 | /*!
64 | @property supportedPixelFormats
65 | @abstract
66 | Indicates the supported pixel formats.
67 | */
68 | @property (nonatomic, copy) NSArray<NSNumber *> *supportedPixelFormats;
69 |
70 | /*!
71 | @property supportedAudioDescriptors
72 | @abstract
73 | Indicates the supported audio descriptors.
74 | */
75 | @property (nonatomic, copy) NSArray<SGAudioDescriptor *> *supportedAudioDescriptors;
76 |
77 | /*!
78 | @property resetFrameRate
79 | @abstract
80 | Indicates whether video decoder needs reset frame rate.
81 | Default is NO.
82 | */
83 | @property (nonatomic) BOOL resetFrameRate;
84 |
85 | /*!
86 | @property preferredFrameRate
87 | @abstract
88 | Indicates the preferred video track frame rate.
89 | Default is (1, 25).
90 | */
91 | @property (nonatomic) CMTime preferredFrameRate;
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGOption/SGDecoderOptions.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGDecoderOptions.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/14.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGDecoderOptions.h"
10 | #import "SGAudioRenderer.h"
11 | #import "SGVideoRenderer.h"
12 | #import "SGMapping.h"
13 |
14 | @implementation SGDecoderOptions
15 |
16 | - (id)copyWithZone:(NSZone *)zone
17 | {
18 | SGDecoderOptions *obj = [[SGDecoderOptions alloc] init];
19 | obj->_options = self->_options.copy;
20 | obj->_threadsAuto = self->_threadsAuto;
21 | obj->_refcountedFrames = self->_refcountedFrames;
22 | obj->_hardwareDecodeH264 = self->_hardwareDecodeH264;
23 | obj->_hardwareDecodeH265 = self->_hardwareDecodeH265;
24 | obj->_preferredCVPixelFormat = self->_preferredCVPixelFormat;
25 | obj->_supportedPixelFormats = self->_supportedPixelFormats.copy;
26 | obj->_supportedAudioDescriptors = self->_supportedAudioDescriptors.copy;
27 | obj->_resetFrameRate = self->_resetFrameRate;
28 | obj->_preferredFrameRate = self->_preferredFrameRate;
29 | return obj;
30 | }
31 |
32 | - (instancetype)init
33 | {
34 | if (self = [super init]) {
35 | self->_options = nil;
36 | self->_threadsAuto = YES;
37 | self->_refcountedFrames = YES;
38 | self->_hardwareDecodeH264 = YES;
39 | self->_hardwareDecodeH265 = YES;
40 | self->_preferredCVPixelFormat = SGPixelFormatFF2AV(AV_PIX_FMT_NV12);
41 | self->_supportedPixelFormats = [SGVideoRenderer supportedPixelFormats];
42 | self->_supportedAudioDescriptors = @[[SGAudioRenderer supportedAudioDescriptor]];
43 | self->_resetFrameRate = NO;
44 | self->_preferredFrameRate = CMTimeMake(1, 25);
45 | }
46 | return self;
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGOption/SGDemuxerOptions.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGDemuxerOptions.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/14.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 |
11 | @interface SGDemuxerOptions : NSObject <NSCopying>
12 |
13 | /*!
14 | @property options
15 | @abstract
16 | The options for avformat_open_input.
17 | Default:
18 | @{@"reconnect" : @(1),
19 | @"user-agent" : @"SGPlayer",
20 | @"timeout" : @(20 * 1000 * 1000)}
21 | */
22 | @property (nonatomic, copy) NSDictionary *options;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGOption/SGDemuxerOptions.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGDemuxerOptions.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/14.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGDemuxerOptions.h"
10 |
11 | @implementation SGDemuxerOptions
12 |
13 | - (id)copyWithZone:(NSZone *)zone
14 | {
15 | SGDemuxerOptions *obj = [[SGDemuxerOptions alloc] init];
16 | obj->_options = self->_options.copy;
17 | return obj;
18 | }
19 |
20 | - (instancetype)init
21 | {
22 | if (self = [super init]) {
23 | self->_options = @{@"reconnect" : @(1),
24 | @"user-agent" : @"SGPlayer",
25 | @"timeout" : @(20 * 1000 * 1000)};
26 | }
27 | return self;
28 | }
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGOption/SGOptions.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGOptions.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/29.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGProcessorOptions.h"
11 | #import "SGDecoderOptions.h"
12 | #import "SGDemuxerOptions.h"
13 |
14 | @interface SGOptions : NSObject <NSCopying>
15 |
16 | /*!
17 | @method sharedOptions
18 | @abstract
19 | Globally shared configuration options.
20 | */
21 | + (instancetype)sharedOptions;
22 |
23 | /*!
24 | @property demuxer
25 | @abstract
26 | The options for demuxer.
27 | */
28 | @property (nonatomic, strong) SGDemuxerOptions *demuxer;
29 |
30 | /*!
31 | @property decoder
32 | @abstract
33 | The options for decoder.
34 | */
35 | @property (nonatomic, strong) SGDecoderOptions *decoder;
36 |
37 | /*!
38 | @property processor
39 | @abstract
40 | The options for processor.
41 | */
42 | @property (nonatomic, strong) SGProcessorOptions *processor;
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGOption/SGOptions.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGOptions.m
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/29.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGOptions.h"
10 |
11 | @implementation SGOptions
12 |
13 | + (instancetype)sharedOptions
14 | {
15 | static SGOptions *obj = nil;
16 | static dispatch_once_t onceToken;
17 | dispatch_once(&onceToken, ^{
18 | obj = [[SGOptions alloc] init];
19 | });
20 | return obj;
21 | }
22 |
23 | - (id)copyWithZone:(NSZone *)zone
24 | {
25 | SGOptions *obj = [[SGOptions alloc] init];
26 | obj->_demuxer = self->_demuxer.copy;
27 | obj->_decoder = self->_decoder.copy;
28 | obj->_processor = self->_processor.copy;
29 | return obj;
30 | }
31 |
32 | - (instancetype)init
33 | {
34 | if (self = [super init]) {
35 | self->_demuxer = [[SGDemuxerOptions alloc] init];
36 | self->_decoder = [[SGDecoderOptions alloc] init];
37 | self->_processor = [[SGProcessorOptions alloc] init];
38 | }
39 | return self;
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGOption/SGProcessorOptions.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGProcessorOptions.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/8/13.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 |
11 | @interface SGProcessorOptions : NSObject <NSCopying>
12 |
13 | /*!
14 | @property audioClass
15 | @abstract
16 | The audio frame processor class.
17 | Default is SGAudioProcessor.
18 | */
19 | @property (nonatomic, copy) Class audioClass;
20 |
21 | /*!
22 | @property videoClass
23 | @abstract
24 | The video frame processor class.
25 | Default is SGVideoProcessor.
26 | */
27 | @property (nonatomic, copy) Class videoClass;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGOption/SGProcessorOptions.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGProcessorOptions.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/8/13.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGProcessorOptions.h"
10 | #import "SGAudioProcessor.h"
11 | #import "SGVideoProcessor.h"
12 |
13 | @implementation SGProcessorOptions
14 |
15 | - (id)copyWithZone:(NSZone *)zone
16 | {
17 | SGProcessorOptions *obj = [[SGProcessorOptions alloc] init];
18 | obj->_audioClass = self->_audioClass.copy;
19 | obj->_videoClass = self->_videoClass.copy;
20 | return obj;
21 | }
22 |
23 | - (instancetype)init
24 | {
25 | if (self = [super init]) {
26 | self->_audioClass = [SGAudioProcessor class];
27 | self->_videoClass = [SGVideoProcessor class];
28 | }
29 | return self;
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGPlatform/SGPLFColor.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPLFColor.h
3 | // SGPlatform
4 | //
5 | // Created by Single on 2017/2/24.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "SGPLFObject.h"
10 |
11 | #if SGPLATFORM_TARGET_OS_MAC
12 |
13 | typedef NSColor SGPLFColor;
14 |
15 | #elif SGPLATFORM_TARGET_OS_IPHONE_OR_TV
16 |
17 | typedef UIColor SGPLFColor;
18 |
19 | #endif
20 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGPlatform/SGPLFColor.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGPLFColor.m
3 | // SGPlatform
4 | //
5 | // Created by Single on 2017/2/24.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "SGPLFColor.h"
10 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGPlatform/SGPLFImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPLFImage.h
3 | // SGPlatform
4 | //
5 | // Created by Single on 2017/2/24.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "SGPLFObject.h"
10 | #import <CoreVideo/CoreVideo.h>
11 | #import <CoreImage/CoreImage.h>
12 |
13 | #if SGPLATFORM_TARGET_OS_MAC
14 |
15 | typedef NSImage SGPLFImage;
16 |
17 | #elif SGPLATFORM_TARGET_OS_IPHONE_OR_TV
18 |
19 | typedef UIImage SGPLFImage;
20 |
21 | #endif
22 |
23 | SGPLFImage * SGPLFImageWithCGImage(CGImageRef image);
24 |
25 | // CVPixelBufferRef
26 | SGPLFImage * SGPLFImageWithCVPixelBuffer(CVPixelBufferRef pixelBuffer);
27 | CIImage * SGPLFImageCIImageWithCVPexelBuffer(CVPixelBufferRef pixelBuffer);
28 | CGImageRef SGPLFImageCGImageWithCVPexelBuffer(CVPixelBufferRef pixelBuffer);
29 |
30 | // RGB data buffer
31 | SGPLFImage * SGPLFImageWithRGBData(uint8_t *rgb_data, int linesize, int width, int height);
32 | CGImageRef SGPLFImageCGImageWithRGBData(uint8_t *rgb_data, int linesize, int width, int height);
33 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGPlatform/SGPLFObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPLFObject.h
3 | // SGPlatform
4 | //
5 | // Created by Single on 2017/2/24.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #ifndef SGPLFObject_h
10 | #define SGPLFObject_h
11 |
12 | #import "SGPLFTargets.h"
13 |
14 | #if SGPLATFORM_TARGET_OS_MAC
15 |
16 | #import <Cocoa/Cocoa.h>
17 |
18 | #elif SGPLATFORM_TARGET_OS_IPHONE_OR_TV
19 |
20 | #import <UIKit/UIKit.h>
21 |
22 | #endif
23 |
24 | #endif /* SGPLFObject_h */
25 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGPlatform/SGPLFScreen.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPLFScreen.h
3 | // SGPlatform
4 | //
5 | // Created by Single on 2017/2/24.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "SGPLFObject.h"
10 |
11 | #if SGPLATFORM_TARGET_OS_MAC
12 |
13 | typedef NSScreen SGPLFScreen;
14 |
15 | #elif SGPLATFORM_TARGET_OS_IPHONE_OR_TV
16 |
17 | typedef UIScreen SGPLFScreen;
18 |
19 | #endif
20 |
21 | CGFloat SGPLFScreenGetScale(void);
22 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGPlatform/SGPLFScreen.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGPLFScreen.m
3 | // SGPlatform
4 | //
5 | // Created by Single on 2017/2/24.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "SGPLFScreen.h"
10 |
11 | #if SGPLATFORM_TARGET_OS_MAC
12 |
13 | CGFloat SGPLFScreenGetScale(void)
14 | {
15 | return [NSScreen mainScreen].backingScaleFactor;
16 | }
17 |
18 | #elif SGPLATFORM_TARGET_OS_IPHONE_OR_TV
19 |
20 | CGFloat SGPLFScreenGetScale(void)
21 | {
22 | return [UIScreen mainScreen].scale;
23 | }
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGPlatform/SGPLFTargets.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPLFTargets.h
3 | // SGPlatform
4 | //
5 | // Created by Single on 2017/2/23.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #ifndef SGPLFTargets_h
10 | #define SGPLFTargets_h
11 |
12 | #import <TargetConditionals.h>
13 |
14 | #define SGPLATFORM_TARGET_OS_MAC TARGET_OS_OSX
15 | #define SGPLATFORM_TARGET_OS_IPHONE TARGET_OS_IOS
16 | #define SGPLATFORM_TARGET_OS_TV TARGET_OS_TV
17 |
18 | #define SGPLATFORM_TARGET_OS_MAC_OR_IPHONE (SGPLATFORM_TARGET_OS_MAC || SGPLATFORM_TARGET_OS_IPHONE)
19 | #define SGPLATFORM_TARGET_OS_MAC_OR_TV (SGPLATFORM_TARGET_OS_MAC || SGPLATFORM_TARGET_OS_TV)
20 | #define SGPLATFORM_TARGET_OS_IPHONE_OR_TV (SGPLATFORM_TARGET_OS_IPHONE || SGPLATFORM_TARGET_OS_TV)
21 |
22 | #endif /* SGPLFTargets_h */
23 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGPlatform/SGPLFView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPLFView.h
3 | // SGPlatform
4 | //
5 | // Created by Single on 2017/2/24.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "SGPLFObject.h"
10 | #import "SGPLFImage.h"
11 | #import "SGPLFColor.h"
12 |
13 | #if SGPLATFORM_TARGET_OS_MAC
14 |
15 | typedef NSView SGPLFView;
16 |
17 | #elif SGPLATFORM_TARGET_OS_IPHONE_OR_TV
18 |
19 | typedef UIView SGPLFView;
20 |
21 | #endif
22 |
23 | void SGPLFViewSetBackgroundColor(SGPLFView *view, SGPLFColor *color);
24 | void SGPLFViewInsertSubview(SGPLFView *superView, SGPLFView *subView, NSInteger index);
25 |
26 | SGPLFImage * SGPLFViewGetCurrentSnapshot(SGPLFView *view);
27 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGAudioFormatter.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioFormatter.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/30.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGAudioDescriptor.h"
11 | #import "SGAudioFrame.h"
12 |
13 | @interface SGAudioFormatter : NSObject
14 |
15 | /**
16 | *
17 | */
18 | @property (nonatomic, copy) SGAudioDescriptor *descriptor;
19 |
20 | /**
21 | *
22 | */
23 | - (SGAudioFrame *)format:(SGAudioFrame *)frame;
24 |
25 | /**
26 | *
27 | */
28 | - (SGAudioFrame *)finish;
29 |
30 | /**
31 | *
32 | */
33 | - (void)flush;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGAudioMixer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioMixer.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/29.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGAudioDescriptor.h"
11 | #import "SGAudioFrame.h"
12 | #import "SGCapacity.h"
13 |
14 | @interface SGAudioMixer : NSObject
15 |
16 | + (instancetype)new NS_UNAVAILABLE;
17 | - (instancetype)init NS_UNAVAILABLE;
18 |
19 | /**
20 | *
21 | */
22 | - (instancetype)initWithTracks:(NSArray<SGTrack *> *)tracks weights:(NSArray<NSNumber *> *)weights;
23 |
24 | /**
25 | *
26 | */
27 | @property (nonatomic, copy, readonly) NSArray<SGTrack *> *tracks;
28 |
29 | /**
30 | *
31 | */
32 | @property (nonatomic, copy) NSArray<NSNumber *> *weights;
33 |
34 | /**
35 | *
36 | */
37 | - (SGAudioFrame *)putFrame:(SGAudioFrame *)frame;
38 |
39 | /**
40 | *
41 | */
42 | - (SGAudioFrame *)finish;
43 |
44 | /**
45 | *
46 | */
47 | - (SGCapacity)capacity;
48 |
49 | /**
50 | *
51 | */
52 | - (void)flush;
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGAudioMixerUnit.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioMixerUnit.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/29.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGAudioFrame.h"
11 | #import "SGCapacity.h"
12 |
13 | @interface SGAudioMixerUnit : NSObject
14 |
15 | /**
16 | *
17 | */
18 | @property (nonatomic, readonly) CMTimeRange timeRange;
19 |
20 | /**
21 | *
22 | */
23 | - (BOOL)putFrame:(SGAudioFrame *)frame;
24 |
25 | /**
26 | *
27 | */
28 | - (NSArray<SGAudioFrame *> *)framesToEndTime:(CMTime)endTime;
29 |
30 | /**
31 | *
32 | */
33 | - (SGCapacity)capacity;
34 |
35 | /**
36 | *
37 | */
38 | - (void)flush;
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGAudioMixerUnit.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioMixerUnit.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/29.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGAudioMixerUnit.h"
10 |
11 | @interface SGAudioMixerUnit ()
12 |
13 | {
14 | SGCapacity _capacity;
15 | }
16 |
17 | @property (nonatomic, strong, readonly) NSMutableArray<SGAudioFrame *> *frames;
18 |
19 | @end
20 |
21 | @implementation SGAudioMixerUnit
22 |
23 | - (instancetype)init
24 | {
25 | if (self = [super init]) {
26 | [self flush];
27 | }
28 | return self;
29 | }
30 |
31 | - (void)dealloc
32 | {
33 | for (SGAudioFrame *obj in self->_frames) {
34 | [obj unlock];
35 | }
36 | }
37 |
38 | #pragma mark - Control
39 |
40 | - (BOOL)putFrame:(SGAudioFrame *)frame
41 | {
42 | if (CMTIMERANGE_IS_VALID(self->_timeRange) &&
43 | CMTimeCompare(CMTimeAdd(frame.timeStamp, frame.duration), CMTimeRangeGetEnd(self->_timeRange)) <= 0) {
44 | return NO;
45 | }
46 | [frame lock];
47 | [self->_frames addObject:frame];
48 | [self updateTimeRange];
49 | return YES;
50 | }
51 |
52 | - (NSArray<SGAudioFrame *> *)framesToEndTime:(CMTime)endTime
53 | {
54 | NSMutableArray<SGAudioFrame *> *ret = [NSMutableArray array];
55 | NSMutableArray<SGAudioFrame *> *remove = [NSMutableArray array];
56 | for (SGAudioFrame *obj in self->_frames) {
57 | if (CMTimeCompare(obj.timeStamp, endTime) < 0) {
58 | [obj lock];
59 | [ret addObject:obj];
60 | }
61 | if (CMTimeCompare(CMTimeAdd(obj.timeStamp, obj.duration), endTime) <= 0) {
62 | [obj unlock];
63 | [remove addObject:obj];
64 | }
65 | }
66 | [self->_frames removeObjectsInArray:remove];
67 | [self updateTimeRange];
68 | return [ret copy];
69 | }
70 |
71 | - (SGCapacity)capacity
72 | {
73 | return self->_capacity;
74 | }
75 |
76 | - (void)flush
77 | {
78 | for (SGAudioFrame *obj in self->_frames) {
79 | [obj unlock];
80 | }
81 | self->_capacity = SGCapacityCreate();
82 | self->_frames = [NSMutableArray array];
83 | self->_timeRange = kCMTimeRangeInvalid;
84 | }
85 |
86 | #pragma mark - Internal
87 |
88 | - (void)updateTimeRange
89 | {
90 | self->_capacity.count = (int)self->_frames.count;
91 | if (self->_frames.count == 0) {
92 | self->_timeRange = kCMTimeRangeInvalid;
93 | } else {
94 | CMTime start = self->_frames.firstObject.timeStamp;
95 | CMTime end = CMTimeAdd(self->_frames.lastObject.timeStamp, self->_frames.lastObject.duration);
96 | self->_timeRange = CMTimeRangeFromTimeToTime(start, end);
97 | }
98 | }
99 |
100 | @end
101 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGAudioProcessor.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioProcessor.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/28.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGProcessor.h"
10 | #import "SGAudioDescriptor.h"
11 |
12 | @interface SGAudioProcessor : NSObject <SGProcessor>
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGAudioProcessor.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioProcessor.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/11/28.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGAudioProcessor.h"
10 | #import "SGAudioMixer.h"
11 |
12 | @interface SGAudioProcessor ()
13 |
14 | @property (nonatomic, strong, readonly) SGAudioMixer *mixer;
15 | @property (nonatomic, strong, readonly) SGTrackSelection *selection;
16 |
17 | @end
18 |
19 | @implementation SGAudioProcessor
20 |
21 | - (void)setSelection:(SGTrackSelection *)selection action:(SGTrackSelectionAction)action
22 | {
23 | self->_selection = [selection copy];
24 | if (action & SGTrackSelectionActionTracks) {
25 | self->_mixer = [[SGAudioMixer alloc] initWithTracks:selection.tracks weights:selection.weights];
26 | } else if (action & SGTrackSelectionActionWeights) {
27 | self->_mixer.weights = selection.weights;
28 | }
29 | }
30 |
31 | - (__kindof SGFrame *)putFrame:(__kindof SGFrame *)frame
32 | {
33 | if (![frame isKindOfClass:[SGAudioFrame class]] ||
34 | ![self->_selection.tracks containsObject:frame.track]) {
35 | [frame unlock];
36 | return nil;
37 | }
38 | return [self->_mixer putFrame:frame];
39 | }
40 |
41 | - (SGAudioFrame *)finish
42 | {
43 | return [self->_mixer finish];
44 | }
45 |
46 | - (SGCapacity)capacity
47 | {
48 | return [self->_mixer capacity];
49 | }
50 |
51 | - (void)flush
52 | {
53 | [self->_mixer flush];
54 | }
55 |
56 | - (void)close
57 | {
58 | self->_mixer = nil;
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGProcessor.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGProcessor.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/8/13.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGTrackSelection.h"
11 | #import "SGCapacity.h"
12 | #import "SGFrame.h"
13 |
14 | @protocol SGProcessor <NSObject>
15 |
16 | /**
17 | *
18 | */
19 | - (void)setSelection:(SGTrackSelection *)selection action:(SGTrackSelectionAction)action;
20 |
21 | /**
22 | *
23 | */
24 | - (__kindof SGFrame *)putFrame:(__kindof SGFrame *)frame;
25 |
26 | /**
27 | *
28 | */
29 | - (__kindof SGFrame *)finish;
30 |
31 | /**
32 | *
33 | */
34 | - (SGCapacity)capacity;
35 |
36 | /**
37 | *
38 | */
39 | - (void)flush;
40 |
41 | /**
42 | *
43 | */
44 | - (void)close;
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGSWResample.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGSWResample.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/30.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGAudioDescriptor.h"
11 |
12 | @interface SGSWResample : NSObject
13 |
14 | /**
15 | *
16 | */
17 | @property (nonatomic, copy) SGAudioDescriptor *inputDescriptor;
18 | @property (nonatomic, copy) SGAudioDescriptor *outputDescriptor;
19 |
20 | /**
21 | *
22 | */
23 | - (BOOL)open;
24 |
25 | /**
26 | *
27 | */
28 | - (int)write:(uint8_t **)data nb_samples:(int)nb_samples;
29 |
30 | /**
31 | *
32 | */
33 | - (int)read:(uint8_t **)data nb_samples:(int)nb_samples;
34 |
35 | /**
36 | *
37 | */
38 | - (int)delay;
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGSWScale.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGSWScale.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/28.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGVideoDescriptor.h"
11 |
12 | @interface SGSWScale : NSObject
13 |
14 | /**
15 | *
16 | */
17 | + (BOOL)isSupportedInputFormat:(int)format;
18 |
19 | /**
20 | *
21 | */
22 | + (BOOL)isSupportedOutputFormat:(int)format;
23 |
24 | /**
25 | *
26 | */
27 | @property (nonatomic, copy) SGVideoDescriptor *inputDescriptor;
28 |
29 | /**
30 | *
31 | */
32 | @property (nonatomic, copy) SGVideoDescriptor *outputDescriptor;
33 |
34 | /**
35 | *
36 | */
37 | @property (nonatomic) int flags; // SWS_FAST_BILINEAR
38 |
39 | /**
40 | *
41 | */
42 | - (BOOL)open;
43 |
44 | /**
45 | *
46 | */
47 | - (int)convert:(const uint8_t * const [])inputData inputLinesize:(const int[])inputLinesize outputData:(uint8_t * const [])outputData outputLinesize:(const int[])outputLinesize;
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGSWScale.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGSWScale.m
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/28.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGSWScale.h"
10 | #import "SGFFmpeg.h"
11 |
12 | @interface SGSWScale ()
13 |
14 | @property (nonatomic, readonly) struct SwsContext *context;
15 |
16 | @end
17 |
18 | @implementation SGSWScale
19 |
20 | + (BOOL)isSupportedInputFormat:(int)format
21 | {
22 | return sws_isSupportedInput(format) > 0;
23 | }
24 |
25 | + (BOOL)isSupportedOutputFormat:(int)format
26 | {
27 | return sws_isSupportedOutput(format) > 0;
28 | }
29 |
30 | - (instancetype)init
31 | {
32 | if (self = [super init]) {
33 | self->_flags = SWS_FAST_BILINEAR;
34 | }
35 | return self;
36 | }
37 |
38 | - (void)dealloc
39 | {
40 | if (self->_context) {
41 | sws_freeContext(self->_context);
42 | self->_context = nil;
43 | }
44 | }
45 |
46 | - (BOOL)open
47 | {
48 | if (!self->_inputDescriptor ||
49 | !self->_outputDescriptor) {
50 | return NO;
51 | }
52 | self->_context = sws_getCachedContext(self->_context,
53 | self->_inputDescriptor.width,
54 | self->_inputDescriptor.height,
55 | self->_inputDescriptor.format,
56 | self->_outputDescriptor.width,
57 | self->_outputDescriptor.height,
58 | self->_outputDescriptor.format,
59 | self->_flags,
60 | NULL, NULL, NULL);
61 | return self->_context ? YES : NO;
62 | }
63 |
64 | - (int)convert:(const uint8_t *const [])inputData inputLinesize:(const int [])inputLinesize outputData:(uint8_t *const [])outputData outputLinesize:(const int [])outputLinesize
65 | {
66 | return sws_scale(self->_context,
67 | inputData,
68 | inputLinesize,
69 | 0,
70 | self->_inputDescriptor.height,
71 | outputData,
72 | outputLinesize);
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGSonic.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGSonic.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/12/20.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGAudioDescriptor.h"
11 |
12 | @interface SGSonic : NSObject
13 |
14 | /**
15 | *
16 | */
17 | + (instancetype)new NS_UNAVAILABLE;
18 | - (instancetype)init NS_UNAVAILABLE;
19 |
20 | /**
21 | *
22 | */
23 | - (instancetype)initWithDescriptor:(SGAudioDescriptor *)descriptor;
24 |
25 | /**
26 | *
27 | */
28 | @property (nonatomic, copy, readonly) SGAudioDescriptor *descriptor;
29 |
30 | /**
31 | *
32 | */
33 | @property (nonatomic) float speed;
34 |
35 | /**
36 | *
37 | */
38 | @property (nonatomic) float pitch;
39 |
40 | /**
41 | *
42 | */
43 | @property (nonatomic) float rate;
44 |
45 | /**
46 | *
47 | */
48 | @property (nonatomic) float volume;
49 |
50 | /**
51 | *
52 | */
53 | - (BOOL)open;
54 |
55 | /**
56 | *
57 | */
58 | - (int)flush;
59 |
60 | /**
61 | *
62 | */
63 | - (int)samplesInput;
64 |
65 | /**
66 | *
67 | */
68 | - (int)samplesAvailable;
69 |
70 | /**
71 | *
72 | */
73 | - (int)write:(uint8_t **)data nb_samples:(int)nb_samples;
74 |
75 | /**
76 | *
77 | */
78 | - (int)read:(uint8_t **)data nb_samples:(int)nb_samples;
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGVideoProcessor.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGVideoProcessor.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/8/13.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGProcessor.h"
10 |
11 | @interface SGVideoProcessor : NSObject <SGProcessor>
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGProcessor/SGVideoProcessor.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGVideoProcessor.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/8/13.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGVideoProcessor.h"
10 | #import "SGVideoFrame.h"
11 |
12 | @interface SGVideoProcessor ()
13 |
14 | @property (nonatomic, strong, readonly) SGTrackSelection *selection;
15 |
16 | @end
17 |
18 | @implementation SGVideoProcessor
19 |
20 | - (void)setSelection:(SGTrackSelection *)selection action:(SGTrackSelectionAction)action
21 | {
22 | self->_selection = [selection copy];
23 | }
24 |
25 | - (__kindof SGFrame *)putFrame:(__kindof SGFrame *)frame
26 | {
27 | if (![frame isKindOfClass:[SGVideoFrame class]] ||
28 | ![self->_selection.tracks containsObject:frame.track]) {
29 | [frame unlock];
30 | return nil;
31 | }
32 | return frame;
33 | }
34 |
35 | - (__kindof SGFrame *)finish
36 | {
37 | return nil;
38 | }
39 |
40 | - (SGCapacity)capacity
41 | {
42 | return SGCapacityCreate();
43 | }
44 |
45 | - (void)flush
46 | {
47 |
48 | }
49 |
50 | - (void)close
51 | {
52 |
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGRenderer/SGAudioRenderer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGAudioRenderer.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/19.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGAudioDescriptor.h"
11 |
12 | @interface SGAudioRenderer : NSObject
13 |
14 | /*!
15 | @method supportedAudioDescriptor
16 | @abstract
17 | Indicates all supported audio descriptor.
18 | */
19 | + (SGAudioDescriptor *)supportedAudioDescriptor;
20 |
21 | /*!
22 | @property pitch
23 | @abstract
24 | Indicates the current pitch.
25 | */
26 | @property (nonatomic) Float64 pitch;
27 |
28 | /*!
29 | @property volume
30 | @abstract
31 | Indicates the current volume.
32 | */
33 | @property (nonatomic) Float64 volume;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGRenderer/SGClock+Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGRenderer+Internal.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/11/1.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGClock.h"
10 | #import "SGDefines.h"
11 |
12 | @protocol SGClockDelegate;
13 |
14 | @interface SGClock ()
15 |
16 | /**
17 | *
18 | */
19 | @property (nonatomic, weak) id<SGClockDelegate> delegate;
20 |
21 | /**
22 | *
23 | */
24 | @property (nonatomic) Float64 rate;
25 |
26 | /**
27 | *
28 | */
29 | @property (nonatomic, readonly) CMTime currentTime;
30 |
31 | /**
32 | *
33 | */
34 | - (void)setAudioTime:(CMTime)time running:(BOOL)running;
35 |
36 | /**
37 | *
38 | */
39 | - (void)setVideoTime:(CMTime)time;
40 |
41 | /**
42 | *
43 | */
44 | - (BOOL)open;
45 |
46 | /**
47 | *
48 | */
49 | - (BOOL)close;
50 |
51 | /**
52 | *
53 | */
54 | - (BOOL)pause;
55 |
56 | /**
57 | *
58 | */
59 | - (BOOL)resume;
60 |
61 | /**
62 | *
63 | */
64 | - (BOOL)flush;
65 |
66 | @end
67 |
68 | @protocol SGClockDelegate <NSObject>
69 |
70 | /**
71 | *
72 | */
73 | - (void)clock:(SGClock *)clock didChcnageCurrentTime:(CMTime)currentTime;
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGRenderer/SGClock.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGClock.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/6/14.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 |
11 | @interface SGClock : NSObject
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGRenderer/SGRenderTimer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGRenderTimer.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/28.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 |
11 | @interface SGRenderTimer : NSObject
12 |
13 | - (instancetype)initWithHandler:(dispatch_block_t)handler;
14 |
15 | @property (nonatomic) NSTimeInterval timeInterval;
16 | @property (nonatomic) BOOL paused;
17 |
18 | - (void)start;
19 | - (void)stop;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGRenderer/SGRenderTimer.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGRenderTimer.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/6/28.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import "SGRenderTimer.h"
10 |
11 | @interface SGRenderTimer ()
12 |
13 | @property (nonatomic, copy) dispatch_block_t handler;
14 | @property (nonatomic, strong) NSTimer *timer;
15 |
16 | @end
17 |
18 | @implementation SGRenderTimer
19 |
20 | - (instancetype)initWithHandler:(dispatch_block_t)handler
21 | {
22 | if (self = [super init]) {
23 | self.handler = handler;
24 | }
25 | return self;
26 | }
27 |
28 | - (void)dealloc
29 | {
30 | [self stop];
31 | }
32 |
33 | - (void)timerHandler
34 | {
35 | if (self.handler) {
36 | self.handler();
37 | }
38 | }
39 |
40 | - (void)setTimeInterval:(NSTimeInterval)timeInterval
41 | {
42 | if (self->_timeInterval != timeInterval) {
43 | self->_timeInterval = timeInterval;
44 | [self start];
45 | }
46 | }
47 |
48 | - (void)setPaused:(BOOL)paused
49 | {
50 | if (self->_paused != paused) {
51 | self->_paused = paused;
52 | [self fire];
53 | }
54 | }
55 |
56 | - (void)start
57 | {
58 | [self stop];
59 | self->_timer = [NSTimer timerWithTimeInterval:self->_timeInterval
60 | target:self
61 | selector:@selector(timerHandler)
62 | userInfo:nil
63 | repeats:YES];
64 | [[NSRunLoop mainRunLoop] addTimer:self->_timer
65 | forMode:NSRunLoopCommonModes];
66 | [self fire];
67 | }
68 |
69 | - (void)stop
70 | {
71 | [self->_timer invalidate];
72 | self->_timer = nil;
73 | }
74 |
75 | - (void)fire
76 | {
77 | self->_timer.fireDate =
78 | self->_paused ?
79 | [NSDate distantFuture] :
80 | [NSDate distantPast];
81 | }
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGRenderer/SGRenderable.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGRenderable.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/19.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGCapacity.h"
11 | #import "SGFrame.h"
12 |
13 | @protocol SGRenderableDelegate;
14 |
15 | /**
16 | *
17 | */
18 | typedef NS_ENUM(NSUInteger, SGRenderableState) {
19 | SGRenderableStateNone = 0,
20 | SGRenderableStateRendering = 1,
21 | SGRenderableStatePaused = 2,
22 | SGRenderableStateFinished = 3,
23 | SGRenderableStateFailed = 4,
24 | };
25 |
26 | @protocol SGRenderable <NSObject>
27 |
28 | /**
29 | *
30 | */
31 | @property (nonatomic, weak) id<SGRenderableDelegate> delegate;
32 |
33 | /**
34 | *
35 | */
36 | @property (nonatomic, readonly) SGRenderableState state;
37 |
38 | /**
39 | *
40 | */
41 | - (SGCapacity)capacity;
42 |
43 | /**
44 | *
45 | */
46 | - (BOOL)open;
47 |
48 | /**
49 | *
50 | */
51 | - (BOOL)close;
52 |
53 | /**
54 | *
55 | */
56 | - (BOOL)pause;
57 |
58 | /**
59 | *
60 | */
61 | - (BOOL)resume;
62 |
63 | /**
64 | *
65 | */
66 | - (BOOL)flush;
67 |
68 | /**
69 | *
70 | */
71 | - (BOOL)finish;
72 |
73 | @end
74 |
75 | @protocol SGRenderableDelegate <NSObject>
76 |
77 | /**
78 | *
79 | */
80 | - (void)renderable:(id<SGRenderable>)renderable didChangeState:(SGRenderableState)state;
81 |
82 | /**
83 | *
84 | */
85 | - (void)renderable:(id<SGRenderable>)renderable didChangeCapacity:(SGCapacity)capacity;
86 |
87 | /**
88 | *
89 | */
90 | - (__kindof SGFrame *)renderable:(id<SGRenderable>)renderable fetchFrame:(SGTimeReader)timeReader;
91 |
92 | @end
93 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGRenderer/SGRenderer+Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGRenderer+Internal.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/11/1.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGRenderable.h"
10 | #import "SGAudioDescriptor.h"
11 | #import "SGAudioRenderer.h"
12 | #import "SGVideoRenderer.h"
13 | #import "SGClock+Internal.h"
14 |
15 | @class SGAudioFormatter;
16 |
17 | @interface SGAudioRenderer () <SGRenderable>
18 |
19 | + (instancetype)new NS_UNAVAILABLE;
20 | - (instancetype)init NS_UNAVAILABLE;
21 |
22 | /**
23 | *
24 | */
25 | - (instancetype)initWithClock:(SGClock *)clock;
26 |
27 | /**
28 | *
29 | */
30 | @property (nonatomic) Float64 rate;
31 |
32 | /**
33 | *
34 | */
35 | @property (nonatomic, copy, readonly) SGAudioDescriptor *descriptor;
36 |
37 | @end
38 |
39 | @interface SGVideoRenderer () <SGRenderable>
40 |
41 | + (instancetype)new NS_UNAVAILABLE;
42 | - (instancetype)init NS_UNAVAILABLE;
43 |
44 | /**
45 | *
46 | */
47 | - (instancetype)initWithClock:(SGClock *)clock;
48 |
49 | /**
50 | *
51 | */
52 | @property (nonatomic) Float64 rate;
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGRenderer/SGVideoRenderer.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGVideoRenderer.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/22.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGVideoFrame.h"
11 | #import "SGVRViewport.h"
12 | #import "SGPLFImage.h"
13 | #import "SGPLFView.h"
14 |
15 | typedef NS_ENUM(NSUInteger, SGDisplayMode) {
16 | SGDisplayModePlane = 0,
17 | SGDisplayModeVR = 1,
18 | SGDisplayModeVRBox = 2,
19 | };
20 |
21 | typedef NS_ENUM(NSUInteger, SGScalingMode) {
22 | SGScalingModeResize = 0,
23 | SGScalingModeResizeAspect = 1,
24 | SGScalingModeResizeAspectFill = 2,
25 | };
26 |
27 | @interface SGVideoRenderer : NSObject
28 |
29 | /*!
30 | @method supportedPixelFormats
31 | @abstract
32 | Indicates all supported pixel formats.
33 | */
34 | + (NSArray<NSNumber *> *)supportedPixelFormats;
35 |
36 | /*!
37 | @method isSupportedInputFormat:
38 | @abstract
39 | Indicates whether the input format is supported.
40 | */
41 | + (BOOL)isSupportedPixelFormat:(int)format;
42 |
43 | /*!
44 | @property view
45 | @abstract
46 | Indicates the view that displays content.
47 |
48 | @discussion
49 | Main thread only.
50 | */
51 | @property (nonatomic, strong) SGPLFView *view;
52 |
53 | /*!
54 | @property viewport
55 | @abstract
56 | Indicates the current vr viewport.
57 |
58 | @discussion
59 | Main thread only.
60 | */
61 | @property (nonatomic, strong, readonly) SGVRViewport *viewport;
62 |
63 | /*!
64 | @property frameOutput
65 | @abstract
66 | Capture the video frame that will be rendered.
67 |
68 | @discussion
69 | Main thread only.
70 | */
71 | @property (nonatomic, copy) void (^frameOutput)(SGVideoFrame *frame);
72 |
73 | /*!
74 | @property preferredFramesPerSecond
75 | @abstract
76 | Indicates how many frames are rendered in one second.
77 | Default is 30.
78 |
79 | @discussion
80 | Main thread only.
81 | */
82 | @property (nonatomic) NSInteger preferredFramesPerSecond;
83 |
84 | /*!
85 | @property scalingMode
86 | @abstract
87 | Indicates current scaling mode.
88 |
89 | @discussion
90 | Main thread only.
91 | */
92 | @property (nonatomic) SGScalingMode scalingMode;
93 |
94 | /*!
95 | @property displayMode
96 | @abstract
97 | Indicates current display mode.
98 |
99 | @discussion
100 | Main thread only.
101 | */
102 | @property (nonatomic) SGDisplayMode displayMode;
103 |
104 | /*!
105 | @method currentImage
106 | @abstract
107 | Generate a screenshot of the current view.
108 |
109 | @discussion
110 | Main thread only.
111 | */
112 | - (SGPLFImage *)currentImage;
113 |
114 | @end
115 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGSession/SGFrameReader.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGFrameReader.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2019/11/12.
6 | // Copyright © 2019 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGDemuxerOptions.h"
11 | #import "SGDecoderOptions.h"
12 | #import "SGAsset.h"
13 | #import "SGFrame.h"
14 |
15 | @protocol SGFrameReaderDelegate;
16 |
17 | @interface SGFrameReader : NSObject
18 |
19 | + (instancetype)new NS_UNAVAILABLE;
20 | - (instancetype)init NS_UNAVAILABLE;
21 |
22 | /**
23 | *
24 | */
25 | - (instancetype)initWithAsset:(SGAsset *)asset;
26 |
27 | /**
28 | *
29 | */
30 | @property (nonatomic, copy) SGDemuxerOptions *demuxerOptions;
31 |
32 | /**
33 | *
34 | */
35 | @property (nonatomic, copy) SGDecoderOptions *decoderOptions;
36 |
37 | /**
38 | *
39 | */
40 | @property (nonatomic, weak) id<SGFrameReaderDelegate> delegate;
41 |
42 | /**
43 | *
44 | */
45 | @property (nonatomic, copy, readonly) NSArray<SGTrack *> *tracks;
46 |
47 | /**
48 | *
49 | */
50 | @property (nonatomic, copy, readonly) NSArray<SGTrack *> *selectedTracks;
51 |
52 | /**
53 | *
54 | */
55 | @property (nonatomic, copy, readonly) NSDictionary *metadata;
56 |
57 | /**
58 | *
59 | */
60 | @property (nonatomic, readonly) CMTime duration;
61 |
62 | /**
63 | *
64 | */
65 | - (NSError *)open;
66 |
67 | /**
68 | *
69 | */
70 | - (NSError *)close;
71 |
72 | /**
73 | *
74 | */
75 | - (NSError *)seekable;
76 |
77 | /**
78 | *
79 | */
80 | - (NSError *)seekToTime:(CMTime)time;
81 |
82 | /**
83 | *
84 | */
85 | - (NSError *)seekToTime:(CMTime)time toleranceBefor:(CMTime)toleranceBefor toleranceAfter:(CMTime)toleranceAfter;
86 |
87 | /**
88 | *
89 | */
90 | - (NSError *)selectTracks:(NSArray<SGTrack *> *)tracks;
91 |
92 | /**
93 | *
94 | */
95 | - (NSError *)nextFrame:(__kindof SGFrame **)frame;
96 |
97 | @end
98 |
99 | @protocol SGFrameReaderDelegate <NSObject>
100 |
101 | /**
102 | *
103 | */
104 | - (BOOL)frameReaderShouldAbortBlockingFunctions:(SGFrameReader *)frameReader;
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGSession/SGPlayerItem+Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPlayerItem+Internal.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/10/25.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGPlayerItem.h"
10 | #import "SGProcessorOptions.h"
11 | #import "SGAudioDescriptor.h"
12 | #import "SGDemuxerOptions.h"
13 | #import "SGDecoderOptions.h"
14 | #import "SGCapacity.h"
15 | #import "SGFrame.h"
16 |
17 | @protocol SGPlayerItemDelegate;
18 |
19 | /**
20 | *
21 | */
22 | typedef NS_ENUM(NSUInteger, SGPlayerItemState) {
23 | SGPlayerItemStateNone = 0,
24 | SGPlayerItemStateOpening = 1,
25 | SGPlayerItemStateOpened = 2,
26 | SGPlayerItemStateReading = 3,
27 | SGPlayerItemStateSeeking = 4,
28 | SGPlayerItemStateFinished = 5,
29 | SGPlayerItemStateClosed = 6,
30 | SGPlayerItemStateFailed = 7,
31 | };
32 |
33 | @interface SGPlayerItem ()
34 |
35 | /**
36 | *
37 | */
38 | @property (nonatomic, copy) SGDemuxerOptions *demuxerOptions;
39 |
40 | /**
41 | *
42 | */
43 | @property (nonatomic, copy) SGDecoderOptions *decoderOptions;
44 |
45 | /**
46 | *
47 | */
48 | @property (nonatomic, copy) SGProcessorOptions *processorOptions;
49 |
50 | /**
51 | *
52 | */
53 | @property (nonatomic, weak) id<SGPlayerItemDelegate> delegate;
54 |
55 | /**
56 | *
57 | */
58 | @property (nonatomic, readonly) SGPlayerItemState state;
59 |
60 | /**
61 | *
62 | */
63 | - (BOOL)open;
64 |
65 | /**
66 | *
67 | */
68 | - (BOOL)start;
69 |
70 | /**
71 | *
72 | */
73 | - (BOOL)close;
74 |
75 | /**
76 | *
77 | */
78 | - (BOOL)seekable;
79 |
80 | /**
81 | *
82 | */
83 | - (BOOL)seekToTime:(CMTime)time;
84 |
85 | /**
86 | *
87 | */
88 | - (BOOL)seekToTime:(CMTime)time result:(SGSeekResult)result;
89 |
90 | /**
91 | *
92 | */
93 | - (BOOL)seekToTime:(CMTime)time toleranceBefor:(CMTime)toleranceBefor toleranceAfter:(CMTime)toleranceAfter result:(SGSeekResult)result;
94 |
95 | /**
96 | *
97 | */
98 | - (SGCapacity)capacityWithType:(SGMediaType)type;
99 |
100 | /**
101 | *
102 | */
103 | - (BOOL)isAvailable:(SGMediaType)type;
104 |
105 | /**
106 | *
107 | */
108 | - (BOOL)isFinished:(SGMediaType)type;
109 |
110 | /**
111 | *
112 | */
113 | - (__kindof SGFrame *)copyAudioFrame:(SGTimeReader)timeReader;
114 | - (__kindof SGFrame *)copyVideoFrame:(SGTimeReader)timeReader;
115 |
116 | @end
117 |
118 | @protocol SGPlayerItemDelegate <NSObject>
119 |
120 | /**
121 | *
122 | */
123 | - (void)playerItem:(SGPlayerItem *)playerItem didChangeState:(SGPlayerItemState)state;
124 |
125 | /**
126 | *
127 | */
128 | - (void)playerItem:(SGPlayerItem *)playerItem didChangeCapacity:(SGCapacity)capacity type:(SGMediaType)type;
129 |
130 | @end
131 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGSession/SGPlayerItem.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPlayerItem.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/1/16.
6 | // Copyright © 2018年 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import "SGTrackSelection.h"
11 | #import "SGAsset.h"
12 | #import "SGTrack.h"
13 |
14 | @interface SGPlayerItem : NSObject
15 |
16 | + (instancetype)new NS_UNAVAILABLE;
17 | - (instancetype)init NS_UNAVAILABLE;
18 |
19 | /*!
20 | @method initWithAsset:
21 | @abstract
22 | Initializes an SGPlayerItem with asset.
23 | */
24 | - (instancetype)initWithAsset:(SGAsset *)asset;
25 |
26 | /*!
27 | @property error
28 | @abstract
29 | If the loading item failed, this describes the error that caused the failure.
30 | */
31 | @property (nonatomic, copy, readonly) NSError *error;
32 |
33 | /*!
34 | @property tracks
35 | @abstract
36 | Provides array of SGPlayerItem tracks.
37 | */
38 | @property (nonatomic, copy, readonly) NSArray<SGTrack *> *tracks;
39 |
40 | /*!
41 | @property duration
42 | @abstract
43 | Indicates the metadata of the item.
44 | */
45 | @property (nonatomic, copy, readonly) NSDictionary *metadata;
46 |
47 | /*!
48 | @property duration
49 | @abstract
50 | Indicates the duration of the item.
51 | */
52 | @property (nonatomic, readonly) CMTime duration;
53 |
54 | /*!
55 | @property duration
56 | @abstract
57 | Indicates the audioSelection of the item.
58 | */
59 | @property (nonatomic, copy, readonly) SGTrackSelection *audioSelection;
60 |
61 | /*!
62 | @method setAudioSelection:action:
63 | @abstract
64 | Select specific audio tracks.
65 | */
66 | - (void)setAudioSelection:(SGTrackSelection *)audioSelection action:(SGTrackSelectionAction)action;
67 |
68 | /*!
69 | @property duration
70 | @abstract
71 | Indicates the videoSelection of the item.
72 | */
73 | @property (nonatomic, copy, readonly) SGTrackSelection *videoSelection;
74 |
75 | /*!
76 | @method setVideoSelection:action:
77 | @abstract
78 | Select specific video tracks.
79 | */
80 | - (void)setVideoSelection:(SGTrackSelection *)videoSelection action:(SGTrackSelectionAction)action;
81 |
82 | @end
83 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGVR/SGMotionSensor.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGMotionSensor.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/23.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import <GLKit/GLKit.h>
11 |
12 | @interface SGMotionSensor : NSObject
13 |
14 | @property (nonatomic, readonly) BOOL ready;
15 | @property (nonatomic, readonly) GLKMatrix4 matrix;
16 |
17 | - (void)start;
18 | - (void)stop;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGVR/SGVRProjection.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGVRProjection.h
3 | // SGPlayer iOS
4 | //
5 | // Created by Single on 2018/8/23.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 | #import <GLKit/GLKit.h>
11 | #import "SGVRViewport.h"
12 |
13 | @interface SGVRProjection : NSObject
14 |
15 | @property (nonatomic, strong) SGVRViewport * viewport;
16 |
17 | - (BOOL)ready;
18 | - (BOOL)matrixWithAspect:(Float64)aspect matrix1:(GLKMatrix4 *)matrix1;
19 | - (BOOL)matrixWithAspect:(Float64)aspect matrix1:(GLKMatrix4 *)matrix1 matrix2:(GLKMatrix4 *)matrix2;
20 |
21 | @end
22 |
23 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGVR/SGVRViewport.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGVRViewport.h
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/8/27.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import <Foundation/Foundation.h>
10 |
11 | @interface SGVRViewport : NSObject
12 |
13 | @property (nonatomic) Float64 degress; // Default value is 60.
14 | @property (nonatomic) Float64 x; // Default value is 0, range is (-360, 360).
15 | @property (nonatomic) Float64 y; // Default value is 0, range is (-360, 360).
16 | @property (nonatomic) BOOL flipX; // Default value is NO.
17 | @property (nonatomic) BOOL flipY; // Default value is NO.
18 | @property (nonatomic) BOOL sensorEnable; // Default value is YES.
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/SGPlayer/Classes/Core/SGVR/SGVRViewport.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGVRViewport.m
3 | // SGPlayer
4 | //
5 | // Created by Single on 2018/8/27.
6 | // Copyright © 2018 single. All rights reserved.
7 | //
8 |
9 | #import "SGVRViewport.h"
10 |
11 | @implementation SGVRViewport
12 |
13 | - (instancetype)init
14 | {
15 | if (self = [super init]) {
16 | self.degress = 60;
17 | self.x = 0;
18 | self.y = 0;
19 | self.flipX = NO;
20 | self.flipY = NO;
21 | self.sensorEnable = YES;
22 | }
23 | return self;
24 | }
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/SGPlayer/Info.plist:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 | <plist version="1.0">
4 | <dict>
5 | <key>CFBundleDevelopmentRegion</key>
6 | <string>en</string>
7 | <key>CFBundleDisplayName</key>
8 | <string>SGPlayer</string>
9 | <key>CFBundleExecutable</key>
10 | <string>$(EXECUTABLE_NAME)</string>
11 | <key>CFBundleIdentifier</key>
12 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13 | <key>CFBundleInfoDictionaryVersion</key>
14 | <string>6.0</string>
15 | <key>CFBundleName</key>
16 | <string>$(PRODUCT_NAME)</string>
17 | <key>CFBundlePackageType</key>
18 | <string>FMWK</string>
19 | <key>CFBundleShortVersionString</key>
20 | <string>2.0.0</string>
21 | <key>CFBundleVersion</key>
22 | <string>$(CURRENT_PROJECT_VERSION)</string>
23 | <key>NSHumanReadableCopyright</key>
24 | <string>Copyright © 2017年 single. All rights reserved.</string>
25 | <key>NSPrincipalClass</key>
26 | <string></string>
27 | </dict>
28 | </plist>
29 |
--------------------------------------------------------------------------------
/SGPlayer/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module SGPlayer {
2 | umbrella header "SGPlayer.h"
3 | export *
4 | module * { export * }
5 | }
6 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | PLATFORM=$1
6 | ACTION=$2
7 |
8 | FFMPEG_VERSION=7.0.1
9 | OPENSSL_VERSION=OpenSSL_1_1_1w
10 |
11 | if [ "$ACTION" = "build" ]; then
12 | sh scripts/init-openssl.sh $PLATFORM $OPENSSL_VERSION
13 | sh scripts/init-ffmpeg.sh $PLATFORM $FFMPEG_VERSION
14 | sh scripts/compile-openssl.sh $PLATFORM "build"
15 | sh scripts/compile-ffmpeg.sh $PLATFORM "build"
16 | elif [ "$ACTION" = "clean" ]; then
17 | sh scripts/compile-openssl.sh $PLATFORM "clean"
18 | sh scripts/compile-ffmpeg.sh $PLATFORM "clean"
19 | else
20 | echo "Usage:"
21 | echo " sh build.sh iOS build"
22 | echo " sh build.sh iOS clean"
23 | echo " ---"
24 | echo " sh build.sh tvOS build"
25 | echo " sh build.sh tvOS clean"
26 | echo " ---"
27 | echo " sh build.sh macOS build"
28 | echo " sh build.sh macOS clean"
29 | exit 1
30 | fi
31 |
--------------------------------------------------------------------------------
/demo/demo-assset/google-help-vr.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-assset/google-help-vr.mp4
--------------------------------------------------------------------------------
/demo/demo-assset/i-see-fire.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-assset/i-see-fire.mp4
--------------------------------------------------------------------------------
/demo/demo-common/SGVideoItem.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGVideoItem.h
3 | // demo-common
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import <SGPlayer/SGPlayer.h>
10 |
11 | @interface SGVideoItem : NSObject
12 |
13 | @property (nonatomic, copy) NSString *name;
14 | @property (nonatomic, copy) SGAsset *asset;
15 | @property (nonatomic) SGDisplayMode displayMode;
16 |
17 | + (NSArray<SGVideoItem *> *)videoItems;
18 |
19 | @end
20 |
21 |
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <Workspace
3 | version = "1.0">
4 | <FileRef
5 | location = "self:demo-ios.xcodeproj">
6 | </FileRef>
7 | </Workspace>
8 |
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // demo-ios
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import <UIKit/UIKit.h>
10 |
11 | @interface AppDelegate : UIResponder <UIApplicationDelegate>
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
17 |
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // demo-ios
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import <AVFoundation/AVFoundation.h>
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
19 | {
20 | [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
21 | return YES;
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-Notification@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-Notification@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-Small@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-Small@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-Small-40@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-Small-40@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-60@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-60@3x.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "1024x1024",
53 | "idiom" : "ios-marketing",
54 | "filename" : "logo.png",
55 | "scale" : "1x"
56 | }
57 | ],
58 | "info" : {
59 | "version" : 1,
60 | "author" : "xcode"
61 | }
62 | }
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Notification@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Notification@3x.png
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-ios/demo-ios/Assets.xcassets/AppIcon.appiconset/logo.png
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 | <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3 | <dependencies>
4 | <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
5 | <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
6 | </dependencies>
7 | <scenes>
8 | <!--View Controller-->
9 | <scene sceneID="EHf-IW-A2E">
10 | <objects>
11 | <viewController id="01J-lp-oVM" sceneMemberID="viewController">
12 | <layoutGuides>
13 | <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
14 | <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
15 | </layoutGuides>
16 | <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
17 | <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
18 | <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
19 | <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
20 | </view>
21 | </viewController>
22 | <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
23 | </objects>
24 | <point key="canvasLocation" x="53" y="375"/>
25 | </scene>
26 | </scenes>
27 | </document>
28 |
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/Info.plist:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 | <plist version="1.0">
4 | <dict>
5 | <key>CFBundleDevelopmentRegion</key>
6 | <string>en</string>
7 | <key>CFBundleDisplayName</key>
8 | <string>SGPlayer</string>
9 | <key>CFBundleExecutable</key>
10 | <string>$(EXECUTABLE_NAME)</string>
11 | <key>CFBundleIdentifier</key>
12 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13 | <key>CFBundleInfoDictionaryVersion</key>
14 | <string>6.0</string>
15 | <key>CFBundleName</key>
16 | <string>$(PRODUCT_NAME)</string>
17 | <key>CFBundlePackageType</key>
18 | <string>APPL</string>
19 | <key>CFBundleShortVersionString</key>
20 | <string>1.0.0</string>
21 | <key>CFBundleVersion</key>
22 | <string>1</string>
23 | <key>LSRequiresIPhoneOS</key>
24 | <true/>
25 | <key>NSAppTransportSecurity</key>
26 | <dict>
27 | <key>NSAllowsArbitraryLoads</key>
28 | <true/>
29 | </dict>
30 | <key>UIBackgroundModes</key>
31 | <array>
32 | <string>audio</string>
33 | </array>
34 | <key>UILaunchStoryboardName</key>
35 | <string>LaunchScreen</string>
36 | <key>UIMainStoryboardFile</key>
37 | <string>Main</string>
38 | <key>UIRequiredDeviceCapabilities</key>
39 | <array>
40 | <string>armv7</string>
41 | </array>
42 | <key>UISupportedInterfaceOrientations</key>
43 | <array>
44 | <string>UIInterfaceOrientationPortrait</string>
45 | <string>UIInterfaceOrientationLandscapeLeft</string>
46 | <string>UIInterfaceOrientationLandscapeRight</string>
47 | </array>
48 | </dict>
49 | </plist>
50 |
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/SGListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGListViewController.h
3 | // demo-ios
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import <UIKit/UIKit.h>
10 |
11 | @interface SGListViewController : UITableViewController
12 |
13 | @end
14 |
15 |
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/SGListViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGListViewController.m
3 | // demo-ios
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "SGListViewController.h"
10 | #import "SGPlayViewController.h"
11 | #import "SGVideoItem.h"
12 |
13 | @interface SGListViewController ()
14 |
15 | @property (nonatomic, strong) NSArray<SGVideoItem *> *videoItems;
16 |
17 | @end
18 |
19 | @implementation SGListViewController
20 |
21 | - (void)viewDidLoad
22 | {
23 | [super viewDidLoad];
24 | self.videoItems = [SGVideoItem videoItems];
25 | }
26 |
27 | - (void)viewWillDisappear:(BOOL)animated
28 | {
29 | [super viewWillDisappear:animated];
30 | [self.navigationController setNavigationBarHidden:YES animated:YES];
31 | }
32 |
33 | - (void)viewWillAppear:(BOOL)animated
34 | {
35 | [super viewWillAppear:animated];
36 | [self.navigationController setNavigationBarHidden:NO animated:YES];
37 | }
38 |
39 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
40 | {
41 | return 1;
42 | }
43 |
44 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
45 | {
46 | return self.videoItems.count;
47 | }
48 |
49 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
50 | {
51 | UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
52 | cell.textLabel.text = self.videoItems[indexPath.row].name;
53 | return cell;
54 | }
55 |
56 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
57 | {
58 | SGPlayViewController *vc = [[SGPlayViewController alloc] init];
59 | vc.videoItem = self.videoItems[indexPath.row];
60 | [self.navigationController pushViewController:vc animated:YES];
61 | }
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/SGPlayViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPlayViewController.h
3 | // demo-ios
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import <UIKit/UIKit.h>
10 | #import "SGVideoItem.h"
11 |
12 | @interface SGPlayViewController : UIViewController
13 |
14 | @property (nonatomic, strong) SGVideoItem *videoItem;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/demo/demo-ios/demo-ios/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // demo-ios
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import <UIKit/UIKit.h>
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <Workspace
3 | version = "1.0">
4 | <FileRef
5 | location = "self:demo-macos.xcodeproj">
6 | </FileRef>
7 | </Workspace>
8 |
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // demo-macos
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import <Cocoa/Cocoa.h>
10 |
11 | @interface AppDelegate : NSObject <NSApplicationDelegate>
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // demo-macos
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
18 | // Insert code here to initialize your application
19 | }
20 |
21 |
22 | - (void)applicationWillTerminate:(NSNotification *)aNotification {
23 | // Insert code here to tear down your application
24 | }
25 |
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "icon_16x16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "icon_16x16@2x.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "icon_32x32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "icon_32x32@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "icon_128x128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "icon_128x128@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "icon_256x256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "icon_256x256@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "icon_512x512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "icon_512x512@2x.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_128x128.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_16x16.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_256x256.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_32x32.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_512x512.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/demo/demo-macos/demo-macos/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/Info.plist:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 | <plist version="1.0">
4 | <dict>
5 | <key>CFBundleDevelopmentRegion</key>
6 | <string>en</string>
7 | <key>CFBundleExecutable</key>
8 | <string>$(EXECUTABLE_NAME)</string>
9 | <key>CFBundleIconFile</key>
10 | <string></string>
11 | <key>CFBundleIdentifier</key>
12 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13 | <key>CFBundleInfoDictionaryVersion</key>
14 | <string>6.0</string>
15 | <key>CFBundleName</key>
16 | <string>$(PRODUCT_NAME)</string>
17 | <key>CFBundlePackageType</key>
18 | <string>APPL</string>
19 | <key>CFBundleShortVersionString</key>
20 | <string>1.0.0</string>
21 | <key>CFBundleVersion</key>
22 | <string>1</string>
23 | <key>LSApplicationCategoryType</key>
24 | <string>public.app-category.video</string>
25 | <key>LSMinimumSystemVersion</key>
26 | <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
27 | <key>NSAppTransportSecurity</key>
28 | <dict>
29 | <key>NSAllowsArbitraryLoads</key>
30 | <true/>
31 | </dict>
32 | <key>NSHumanReadableCopyright</key>
33 | <string>Copyright © 2017年 single. All rights reserved.</string>
34 | <key>NSMainStoryboardFile</key>
35 | <string>Main</string>
36 | <key>NSPrincipalClass</key>
37 | <string>NSApplication</string>
38 | </dict>
39 | </plist>
40 |
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/SGListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGListViewController.h
3 | // demo-macos
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import <Cocoa/Cocoa.h>
10 |
11 | @interface SGListViewController : NSViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/SGListViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SGListViewController.m
3 | // demo-macos
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import "SGListViewController.h"
10 | #import "SGPlayViewController.h"
11 | #import "SGVideoItem.h"
12 |
13 | @interface SGListViewController ()
14 |
15 | @property (weak) IBOutlet NSPopUpButton *popUpButton;
16 | @property (nonatomic, strong) NSArray<SGVideoItem *> *videoItems;
17 |
18 | @end
19 |
20 | @implementation SGListViewController
21 |
22 | - (void)viewDidLoad
23 | {
24 | [super viewDidLoad];
25 | [self.popUpButton removeAllItems];
26 | self.videoItems = [SGVideoItem videoItems];
27 | for (NSUInteger i = 0; i < self.videoItems.count; i++) {
28 | [self.popUpButton addItemWithTitle:self.videoItems[i].name];
29 | }
30 | }
31 |
32 | - (void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender
33 | {
34 | SGPlayViewController *vc = (id)[segue.destinationController contentViewController];
35 | vc.videoItem = self.videoItems[self.popUpButton.indexOfSelectedItem];
36 | [vc run];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/SGPlayViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SGPlayViewController.h
3 | // demo-macos
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import <Cocoa/Cocoa.h>
10 | #import "SGVideoItem.h"
11 |
12 | @interface SGPlayViewController : NSViewController
13 |
14 | @property (nonatomic, strong) SGVideoItem *videoItem;
15 |
16 | - (void)run;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/demo/demo-macos/demo-macos/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // demo-macos
4 | //
5 | // Created by Single on 2017/3/15.
6 | // Copyright © 2017年 single. All rights reserved.
7 | //
8 |
9 | #import <Cocoa/Cocoa.h>
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <Workspace
3 | version = "1.0">
4 | <FileRef
5 | location = "self:demo-tvos.xcodeproj">
6 | </FileRef>
7 | </Workspace>
8 |
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 | <plist version="1.0">
4 | <dict>
5 | <key>IDEDidComputeMac32BitWarning</key>
6 | <true/>
7 | </dict>
8 | </plist>
9 |
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // demo-tvos
4 | //
5 | // Created by Single on 2018/11/5.
6 | // Copyright © 2018 Single. All rights reserved.
7 | //
8 |
9 | #import <UIKit/UIKit.h>
10 |
11 | @interface AppDelegate : UIResponder <UIApplicationDelegate>
12 |
13 | @property (strong, nonatomic) UIWindow * window;
14 |
15 | @end
16 |
17 |
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // demo-tvos
4 | //
5 | // Created by Single on 2018/11/5.
6 | // Copyright © 2018 Single. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
18 | {
19 | return YES;
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv"
5 | }
6 | ],
7 | "info" : {
8 | "version" : 1,
9 | "author" : "xcode"
10 | }
11 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv"
5 | }
6 | ],
7 | "info" : {
8 | "version" : 1,
9 | "author" : "xcode"
10 | }
11 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv"
5 | }
6 | ],
7 | "info" : {
8 | "version" : 1,
9 | "author" : "xcode"
10 | }
11 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | }
11 | ],
12 | "info" : {
13 | "version" : 1,
14 | "author" : "xcode"
15 | }
16 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | }
11 | ],
12 | "info" : {
13 | "version" : 1,
14 | "author" : "xcode"
15 | }
16 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | }
11 | ],
12 | "info" : {
13 | "version" : 1,
14 | "author" : "xcode"
15 | }
16 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "assets" : [
3 | {
4 | "size" : "1280x768",
5 | "idiom" : "tv",
6 | "filename" : "App Icon - App Store.imagestack",
7 | "role" : "primary-app-icon"
8 | },
9 | {
10 | "size" : "400x240",
11 | "idiom" : "tv",
12 | "filename" : "App Icon.imagestack",
13 | "role" : "primary-app-icon"
14 | },
15 | {
16 | "size" : "2320x720",
17 | "idiom" : "tv",
18 | "filename" : "Top Shelf Image Wide.imageset",
19 | "role" : "top-shelf-image-wide"
20 | },
21 | {
22 | "size" : "1920x720",
23 | "idiom" : "tv",
24 | "filename" : "Top Shelf Image.imageset",
25 | "role" : "top-shelf-image"
26 | }
27 | ],
28 | "info" : {
29 | "version" : 1,
30 | "author" : "xcode"
31 | }
32 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "tv-marketing",
13 | "scale" : "1x"
14 | },
15 | {
16 | "idiom" : "tv-marketing",
17 | "scale" : "2x"
18 | }
19 | ],
20 | "info" : {
21 | "version" : 1,
22 | "author" : "xcode"
23 | }
24 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "tv-marketing",
13 | "scale" : "1x"
14 | },
15 | {
16 | "idiom" : "tv-marketing",
17 | "scale" : "2x"
18 | }
19 | ],
20 | "info" : {
21 | "version" : 1,
22 | "author" : "xcode"
23 | }
24 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="13122.16" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
3 | <dependencies>
4 | <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
5 | <capability name="Safe area layout guides" minToolsVersion="9.0"/>
6 | <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
7 | </dependencies>
8 | <scenes>
9 | <!--View Controller-->
10 | <scene sceneID="tne-QT-ifu">
11 | <objects>
12 | <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
13 | <layoutGuides>
14 | <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
15 | <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
16 | </layoutGuides>
17 | <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
18 | <rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
19 | <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
20 | <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
21 | <viewLayoutGuide key="safeArea" id="wu6-TO-1qx"/>
22 | </view>
23 | </viewController>
24 | <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
25 | </objects>
26 | </scene>
27 | </scenes>
28 | </document>
29 |
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/Info.plist:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 | <plist version="1.0">
4 | <dict>
5 | <key>CFBundleDevelopmentRegion</key>
6 | <string>$(DEVELOPMENT_LANGUAGE)</string>
7 | <key>CFBundleDisplayName</key>
8 | <string>SGPlayer</string>
9 | <key>CFBundleExecutable</key>
10 | <string>$(EXECUTABLE_NAME)</string>
11 | <key>CFBundleIdentifier</key>
12 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13 | <key>CFBundleInfoDictionaryVersion</key>
14 | <string>6.0</string>
15 | <key>CFBundleName</key>
16 | <string>$(PRODUCT_NAME)</string>
17 | <key>CFBundlePackageType</key>
18 | <string>APPL</string>
19 | <key>CFBundleShortVersionString</key>
20 | <string>1.0.0</string>
21 | <key>CFBundleVersion</key>
22 | <string>1</string>
23 | <key>LSRequiresIPhoneOS</key>
24 | <true/>
25 | <key>UIMainStoryboardFile</key>
26 | <string>Main</string>
27 | <key>UIRequiredDeviceCapabilities</key>
28 | <array>
29 | <string>arm64</string>
30 | </array>
31 | <key>UIUserInterfaceStyle</key>
32 | <string>Automatic</string>
33 | </dict>
34 | </plist>
35 |
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // demo-tvos
4 | //
5 | // Created by Single on 2018/11/5.
6 | // Copyright © 2018 Single. All rights reserved.
7 | //
8 |
9 | #import <UIKit/UIKit.h>
10 |
11 | @interface ViewController : UIViewController
12 |
13 | @end
14 |
15 |
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // demo-tvos
4 | //
5 | // Created by Single on 2018/11/5.
6 | // Copyright © 2018 Single. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import <SGPlayer/SGPlayer.h>
11 |
12 | @interface ViewController ()
13 |
14 | @property (nonatomic, assign) BOOL seeking;
15 | @property (nonatomic, strong) SGPlayer *player;
16 |
17 | @end
18 |
19 | @implementation ViewController
20 |
21 | - (instancetype)init
22 | {
23 | if (self = [super init]) {
24 | self.player = [[SGPlayer alloc] init];
25 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(infoChanged:) name:SGPlayerDidChangeInfosNotification object:self.player];
26 | }
27 | return self;
28 | }
29 |
30 | - (void)dealloc
31 | {
32 | [[NSNotificationCenter defaultCenter] removeObserver:self];
33 | }
34 |
35 | - (void)viewDidLoad
36 | {
37 | [super viewDidLoad];
38 |
39 | NSURL *URL = [[NSBundle mainBundle] URLForResource:@"i-see-fire" withExtension:@"mp4"];
40 | SGAsset *asset = [[SGURLAsset alloc] initWithURL:URL];
41 |
42 | self.player.videoRenderer.view = self.view;
43 | [self.player replaceWithAsset:asset];
44 | [self.player play];
45 | }
46 |
47 | #pragma mark - SGPlayer Notifications
48 |
49 | - (void)infoChanged:(NSNotification *)notification
50 | {
51 | SGTimeInfo time = [SGPlayer timeInfoFromUserInfo:notification.userInfo];
52 | SGStateInfo state = [SGPlayer stateInfoFromUserInfo:notification.userInfo];
53 | SGInfoAction action = [SGPlayer infoActionFromUserInfo:notification.userInfo];
54 | if (action & SGInfoActionTime) {
55 | NSLog(@"playback: %f, duration: %f, cached: %f",
56 | CMTimeGetSeconds(time.playback),
57 | CMTimeGetSeconds(time.duration),
58 | CMTimeGetSeconds(time.cached));
59 | }
60 | if (action & SGInfoActionState) {
61 | NSLog(@"player: %d, loading: %d, playback: %d, playing: %d, seeking: %d, finished: %d",
62 | (int)state.player, (int)state.loading, (int)state.playback,
63 | (int)(state.playback & SGPlaybackStatePlaying),
64 | (int)(state.playback & SGPlaybackStateSeeking),
65 | (int)(state.playback & SGPlaybackStateFinished));
66 | }
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/demo/demo-tvos/demo-tvos/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // demo-tvos
4 | //
5 | // Created by Single on 2018/11/5.
6 | // Copyright © 2018 Single. All rights reserved.
7 | //
8 |
9 | #import <UIKit/UIKit.h>
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/demo/demo.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <Workspace
3 | version = "1.0">
4 | <FileRef
5 | location = "group:demo-ios/demo-ios.xcodeproj">
6 | </FileRef>
7 | <FileRef
8 | location = "group:demo-macos/demo-macos.xcodeproj">
9 | </FileRef>
10 | <FileRef
11 | location = "group:demo-tvos/demo-tvos.xcodeproj">
12 | </FileRef>
13 | <FileRef
14 | location = "group:../SGPlayer.xcodeproj">
15 | </FileRef>
16 | </Workspace>
17 |
--------------------------------------------------------------------------------
/demo/demo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 | <plist version="1.0">
4 | <dict>
5 | <key>IDEDidComputeMac32BitWarning</key>
6 | <true/>
7 | </dict>
8 | </plist>
9 |
--------------------------------------------------------------------------------
/demo/demo.xcworkspace/xcshareddata/demo.xcscmblueprint:
--------------------------------------------------------------------------------
1 | {
2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "F23AFB690725856BF6A8F7C02C736922AA443A58",
3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4 |
5 | },
6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
7 | "F23AFB690725856BF6A8F7C02C736922AA443A58" : 9223372036854775807,
8 | "CF9A9AD861EDA5D4368DC40F74298A8979BAE8C8" : 9223372036854775807
9 | },
10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "C8E1264A-1979-46B0-A87B-28155F88CEC8",
11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
12 | "F23AFB690725856BF6A8F7C02C736922AA443A58" : "SGPlayer\/",
13 | "CF9A9AD861EDA5D4368DC40F74298A8979BAE8C8" : "SGPlayer\/Vendors\/SGPlatform\/"
14 | },
15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "demo",
16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "demo\/demo.xcworkspace",
18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19 | {
20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:0x010101\/SGPlatform.git",
21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "CF9A9AD861EDA5D4368DC40F74298A8979BAE8C8"
23 | },
24 | {
25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:0x010101\/SGPlayer.git",
26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "F23AFB690725856BF6A8F7C02C736922AA443A58"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/documents/banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/documents/banner.jpg
--------------------------------------------------------------------------------
/documents/flow-chart.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libobjc/SGPlayer/1d0b304c2f980c73b2c09d8ef417f6734f257f4b/documents/flow-chart.jpg
--------------------------------------------------------------------------------
/scripts/avconfig.h:
--------------------------------------------------------------------------------
1 | /*
2 | * avconfig.h
3 | *
4 | * Copyright (c) 2013 Bilibili
5 | * Copyright (c) 2013 Zhang Rui <bbcallen@gmail.com>
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #if defined(__aarch64__)
25 | # include "arm64/avconfig.h"
26 | #elif defined(__x86_64__)
27 | # include "x86_64/avconfig.h"
28 | #else
29 | # error Unsupport architecture
30 | #endif
31 |
--------------------------------------------------------------------------------
/scripts/config.h:
--------------------------------------------------------------------------------
1 | /*
2 | * config.h
3 | *
4 | * Copyright (c) 2013 Bilibili
5 | * Copyright (c) 2013 Zhang Rui <bbcallen@gmail.com>
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #if defined(__aarch64__)
25 | # include "arm64/config.h"
26 | #elif defined(__x86_64__)
27 | # include "x86_64/config.h"
28 | #else
29 | # error Unsupport architecture
30 | #endif
31 |
--------------------------------------------------------------------------------
/scripts/ffversion.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ffversion.h
3 | *
4 | * Copyright (c) 2013 Bilibili
5 | * Copyright (c) 2013 Zhang Rui <bbcallen@gmail.com>
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #if defined(__aarch64__)
25 | # include "arm64/ffversion.h"
26 | #elif defined(__x86_64__)
27 | # include "x86_64/ffversion.h"
28 | #else
29 | # error Unsupport architecture
30 | #endif
31 |
--------------------------------------------------------------------------------
/scripts/init-ffmpeg.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 | #
3 | # Copyright (C) 2013-2015 Bilibili
4 | # Copyright (C) 2013-2015 Zhang Rui <bbcallen@gmail.com>
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | IJK_FFMPEG_UPSTREAM=https://github.com/libobjc/FFmpeg.git
20 | IJK_FFMPEG_FORK=https://github.com/libobjc/FFmpeg.git
21 | IJK_FFMPEG_COMMIT=$2
22 | IJK_FFMPEG_LOCAL_REPO=build/extra/ffmpeg
23 |
24 | IJK_GASP_UPSTREAM=https://github.com/libav/gas-preprocessor.git
25 | IJK_GASP_LOCAL_REPO=build/extra/gas-preprocessor
26 |
27 | set -e
28 |
29 | FF_ALL_ARCHS=
30 | FF_ALL_ARCHS_IOS="arm64"
31 | FF_ALL_ARCHS_TVOS="arm64"
32 | FF_ALL_ARCHS_MACOS="arm64 x86_64"
33 |
34 | #FF_ALL_ARCHS_IOS="x86_64 arm64-simulator"
35 | #FF_ALL_ARCHS_TVOS="x86_64 arm64-simulator"
36 |
37 | FF_PLATFORM=$1
38 |
39 | function pull_common() {
40 | echo "== pull gas-preprocessor base =="
41 | sh scripts/pull-repo-base.sh $IJK_GASP_UPSTREAM $IJK_GASP_LOCAL_REPO
42 |
43 | echo "== pull ffmpeg base =="
44 | sh scripts/pull-repo-base.sh $IJK_FFMPEG_UPSTREAM $IJK_FFMPEG_LOCAL_REPO
45 | }
46 |
47 | function pull_fork() {
48 | echo "== pull ffmpeg fork $1 =="
49 | sh scripts/pull-repo-ref.sh $IJK_FFMPEG_FORK build/source/$FF_PLATFORM/ffmpeg-$1 ${IJK_FFMPEG_LOCAL_REPO}
50 | cd build/source/$FF_PLATFORM/ffmpeg-$1
51 | git checkout ${IJK_FFMPEG_COMMIT} -B SGPlayer
52 | cd -
53 | }
54 |
55 | function pull_fork_all() {
56 | for ARCH in $FF_ALL_ARCHS
57 | do
58 | pull_fork $ARCH
59 | done
60 | }
61 |
62 | #----------
63 | if [ "$FF_PLATFORM" = "iOS" ]; then
64 | FF_ALL_ARCHS=$FF_ALL_ARCHS_IOS
65 | elif [ "$FF_PLATFORM" = "tvOS" ]; then
66 | FF_ALL_ARCHS=$FF_ALL_ARCHS_TVOS
67 | elif [ "$FF_PLATFORM" = "macOS" ]; then
68 | FF_ALL_ARCHS=$FF_ALL_ARCHS_MACOS
69 | else
70 | echo "You must specific an platform 'iOS, tvOS, macOS'.\n"
71 | exit 1
72 | fi
73 |
74 | pull_common
75 | pull_fork_all
76 |
77 |
--------------------------------------------------------------------------------
/scripts/init-openssl.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 | #
3 | # Copyright (C) 2013-2015 Bilibili
4 | # Copyright (C) 2013-2015 Zhang Rui <bbcallen@gmail.com>
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | IJK_OPENSSL_UPSTREAM=https://github.com/openssl/openssl.git
20 | IJK_OPENSSL_FORK=https://github.com/openssl/openssl.git
21 | IJK_OPENSSL_COMMIT=$2
22 | IJK_OPENSSL_LOCAL_REPO=build/extra/openssl
23 |
24 | set -e
25 |
26 | FF_ALL_ARCHS=
27 | FF_ALL_ARCHS_IOS="arm64"
28 | FF_ALL_ARCHS_TVOS="arm64"
29 | FF_ALL_ARCHS_MACOS="arm64 x86_64"
30 |
31 | #FF_ALL_ARCHS_IOS="x86_64 arm64-simulator"
32 | #FF_ALL_ARCHS_TVOS="x86_64 arm64-simulator"
33 |
34 | FF_PLATFORM=$1
35 |
36 | function pull_common() {
37 | echo "== pull openssl base =="
38 | sh scripts/pull-repo-base.sh $IJK_OPENSSL_UPSTREAM $IJK_OPENSSL_LOCAL_REPO
39 | }
40 |
41 | function pull_fork() {
42 | echo "== pull openssl fork $1 =="
43 | sh scripts/pull-repo-ref.sh $IJK_OPENSSL_FORK build/source/$FF_PLATFORM/openssl-$1 ${IJK_OPENSSL_LOCAL_REPO}
44 | cd build/source/$FF_PLATFORM/openssl-$1
45 | git checkout ${IJK_OPENSSL_COMMIT} -B SGPlayer
46 | cd -
47 | }
48 |
49 | function pull_fork_all() {
50 | for ARCH in $FF_ALL_ARCHS
51 | do
52 | pull_fork $ARCH
53 | done
54 | }
55 |
56 | #----------
57 | if [ "$FF_PLATFORM" = "iOS" ]; then
58 | FF_ALL_ARCHS=$FF_ALL_ARCHS_IOS
59 | elif [ "$FF_PLATFORM" = "tvOS" ]; then
60 | FF_ALL_ARCHS=$FF_ALL_ARCHS_TVOS
61 | elif [ "$FF_PLATFORM" = "macOS" ]; then
62 | FF_ALL_ARCHS=$FF_ALL_ARCHS_MACOS
63 | else
64 | echo "You must specific an platform 'iOS, tvOS, macOS'.\n"
65 | exit 1
66 | fi
67 |
68 | pull_common
69 | pull_fork_all
70 |
71 |
--------------------------------------------------------------------------------
/scripts/pull-repo-base.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | REMOTE_REPO=$1
4 | LOCAL_WORKSPACE=$2
5 |
6 |
7 | if [ -z $REMOTE_REPO -o -z $LOCAL_WORKSPACE ]; then
8 | echo "invalid call pull-repo.sh '$REMOTE_REPO' '$LOCAL_WORKSPACE'"
9 | elif [ ! -d $LOCAL_WORKSPACE ]; then
10 | git clone $REMOTE_REPO $LOCAL_WORKSPACE
11 | else
12 | cd $LOCAL_WORKSPACE
13 | git fetch --all --tags
14 | cd -
15 | fi
16 |
--------------------------------------------------------------------------------
/scripts/pull-repo-ref.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | REMOTE_REPO=$1
4 | LOCAL_WORKSPACE=$2
5 | REF_REPO=$3
6 |
7 | if [ -z $1 -o -z $2 -o -z $3 ]; then
8 | echo "invalid call pull-repo.sh '$1' '$2' '$3'"
9 | elif [ ! -d $LOCAL_WORKSPACE ]; then
10 | git clone --reference $REF_REPO $REMOTE_REPO $LOCAL_WORKSPACE
11 | cd $LOCAL_WORKSPACE
12 | git repack -a
13 | else
14 | cd $LOCAL_WORKSPACE
15 | git fetch --all --tags
16 | cd -
17 | fi
18 |
--------------------------------------------------------------------------------