Skip to content

Commit

Permalink
Merge pull request #12 from kinescope/hotfix/process_feedback
Browse files Browse the repository at this point in the history
First day patch
  • Loading branch information
NullIsOne authored Apr 4, 2024
2 parents 2218ef5 + 5403dd0 commit 8a52a34
Show file tree
Hide file tree
Showing 28 changed files with 158 additions and 91 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
## 0.2.1

### Fixed bugs

- always default player style in fullscreen mode (now it equal to style of mini-player)

### Removed

- hardcoded endpoint for analytics
- hardcoded endpoint constructor for fairplay

Now ths enpoints provided from server.

## 0.2

### Introduced
Expand Down
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PODS:
- KinescopeSDK (0.2-beta):
- KinescopeSDK (0.2.1):
- M3U8Kit (~> 1.0)
- SwiftProtobuf (= 1.26.0)
- M3U8Kit (1.0.2)
Expand All @@ -18,7 +18,7 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
KinescopeSDK: bfa73f82c77d3b21dad41d83bab4109a2168ed26
KinescopeSDK: 46658fde8178bf17feec2c8b24ce2f74ea751be9
M3U8Kit: 6a0d55ba2e62e146f34f53276d7c3aa78ed4fc00
SwiftProtobuf: 5e8349171e7c2f88f5b9e683cb3cb79d1dc780b3

Expand Down
30 changes: 0 additions & 30 deletions Example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,6 @@ This example shows how to use KinescopeSDK.
- install required pods
- generate project and workspace


### Configure apiKeys

Add `KinescopeConfig.plist` at path `{Repository}/Example/KinescopeExample` to add real **apiKey** for testing real user account. **Plist** can store multiple users.

`KinescopeConfig.plist` seems like usual property list.

```plist
<plist version="1.0">
<dict>
<key>user0</key>
<string>666</string>
<key>user1</key>
<string>1234</string>
<key>user2</key>
<string>9876</string>
</dict>
</plist>
```

`key` – convenient user's name, `string` – apiKey

Run `make project` from `{Repository}/Example`

This command will generate project again with reference to config.

If you fill config correctly you got screen with your userNames. Like this

[![List](https://i.ibb.co/NjWHtq0/Simulator-Screen-Shot-i-Phone-8-2021-03-25-at-12-27-59.png)](https://ibb.co/DCwSzFB)

## License

[MIT License](LICENSE)
2 changes: 1 addition & 1 deletion KinescopeSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "KinescopeSDK"
s.version = "0.2"
s.version = "0.2.1"
s.summary = "Library to help you include Kinescope player into your mobile iOS application"
s.homepage = "https://github.com/kinescope/ios-kinescope-player"
s.license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Kinescope iOS SDK

[![Pub Version](https://img.shields.io/badge/version-0.1-orange)](https://img.shields.io/badge/version-0.1-orange)
![Pub Version](https://img.shields.io/badge/version-0.2.1-orange)

This framework created to help you include [Kinescope](https://kinescope.io/) player into your mobile iOS application.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ final class VideoAnalyticDataFactory: Factory {

// MARK: - Properties

private var video: KinescopeVideo?
private(set) var source: KinescopeVideo?

// MARK: - Factory

func provide() -> T? {
guard let video else {
guard let source else {
return nil
}
var result = T()
result.source = video.hlsLink
result.duration = UInt32(video.duration)
result.source = source.hlsLink
result.duration = UInt32(source.duration)
return result
}
}
Expand All @@ -35,6 +35,6 @@ final class VideoAnalyticDataFactory: Factory {

extension VideoAnalyticDataFactory: VideoAnalyticInput {
func setVideo(_ video: KinescopeVideo) {
self.video = video
self.source = video
}
}
5 changes: 4 additions & 1 deletion Sources/KinescopeSDK/Events/InnerEventsProtoHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ class InnerEventsProtoHandler {

extension InnerEventsProtoHandler: InnerEventsHandler {
func send(event: InnerProtoEvent, value: Float) {
service.send(event: build(event: event, value: value))
guard let video = dataStorage.video.source else {
return
}
service.send(event: build(event: event, value: value), for: video)
}

func sendOnce(event: InnerProtoEvent, value: Float) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ extension Manager: KinescopeConfigurable {

func setConfig(_ config: KinescopeConfig) {
self.config = config
self.drmFactory = DefaultDataProtectionHandlerFactory(service: DataProtectionNetworkService(transport: Transport(),
config: config))
self.drmFactory = DefaultDataProtectionHandlerFactory(service: DataProtectionNetworkService(transport: Transport()))
self.assetDownloader = AssetDownloader(fileService: FileNetworkService(downloadIdentifier: "assets"),
assetLinksService: AssetLinksLocalService(config: config))
self.attachmentDownloader = AttachmentDownloader(fileService: FileNetworkService(downloadIdentifier: "attachments"))
Expand Down
6 changes: 1 addition & 5 deletions Sources/KinescopeSDK/Models/KinescopeConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ public struct KinescopeConfig {
let endpoint: String
/// Referer for direct loading of public videos from kinescope
let referer: String
/// Key server
let keyServer: String

/// - parameter endpoint: Root endpoint of kinescope video service
/// - parameter referer: Referer for header
public init(endpoint: String = "https://kinescope.io/",
referer: String = "https://kinescope.io/",
keyServer: String = "https://license.kinescope.io/v1/vod/") {
referer: String = "https://kinescope.io/") {
self.endpoint = endpoint
self.referer = referer
self.keyServer = keyServer
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// KinescopeAnalyticEndpoints.swift
// KinescopeSDK
//
// Created by Nikita Korobeinikov on 04.04.2024.
//

import Foundation

public struct KinescopeAnalyticEndpoints: Codable {
let metricUrl: String
}
12 changes: 12 additions & 0 deletions Sources/KinescopeSDK/Models/Videos/KinescopeDRMData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// KinescopeDRMData.swift
// KinescopeSDK
//
// Created by Nikita Korobeinikov on 04.04.2024.
//

import Foundation

public struct KinescopeDRMData: Codable {
let fairplay: KinescopeFairPlayEndpoints
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// KinescopeFairPlayEndpoints.swift
// KinescopeSDK
//
// Created by Nikita Korobeinikov on 04.04.2024.
//

import Foundation

public struct KinescopeFairPlayEndpoints: Codable {
let certificateUrl: String
let licenseUrl: String
}
27 changes: 26 additions & 1 deletion Sources/KinescopeSDK/Models/Videos/KinescopeVideo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,31 @@ public struct KinescopeVideo: Codable {
public let attachments: [KinescopeVideoAdditionalMaterial]?
public let subtitles: [KinescopeVideoSubtitle]?
public let hlsLink: String
public let dash_link: String?
public let dashLink: String?
public let live: KinescopeStreamMeta?
public let analytic: KinescopeAnalyticEndpoints?
public let drm: KinescopeDRMData?

enum CodingKeys: String, CodingKey {
case id
case workspaceId
case projectId
case folderId
case type
case title
case description
case status
case progress
case duration
case qualityMap
case chapters
case poster
case attachments
case subtitles
case hlsLink
case dashLink
case live
case analytic = "sdk"
case drm
}
}
5 changes: 3 additions & 2 deletions Sources/KinescopeSDK/Player/KinescopeVideoPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public class KinescopeVideoPlayer: KinescopePlayer, KinescopePlayerBody, Fullscr
return
}
isLive = video.type == .live && strategy.player.isReadyToPlay
drmHandler = dependencies.drmFactory.provide(for: video.id)
drmHandler = dependencies.drmFactory.provide(for: video)
analyticStorage.videoInput.setVideo(video)
analyticStorage.sessionInput.resetWatchedDuration()
analytic?.reset()
Expand Down Expand Up @@ -563,7 +563,8 @@ extension KinescopeVideoPlayer: KinescopePlayerViewDelegate {
}

KinescopeFullscreenViewController.present(player: self,
video: video) { [weak self] in
video: video,
with: view.config) { [weak self] in
guard let self else {
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
/// Implementation of ``AnalyticsService`` which can delegate sending to client code
final class AnalyticsLoggingService: AnalyticsService {

func send(event: Analytics_Native) {
func send(event: Analytics_Native, for video: KinescopeVideo) {
Kinescope.analyticDelegate?.didSendAnalytics(event: event.event,
with: event.textFormatString())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,20 @@ final class AnalyticsNetworkService: AnalyticsService {

// MARK: - Public Methods

func send(event: Analytics_Native) {
func send(event: Analytics_Native, for video: KinescopeVideo) {
guard let path = video.analytic?.metricUrl else {
Kinescope.shared.logger?.log(message: "Could not get analytic endpoint", level: KinescopeLoggerLevel.analytics)
return
}

guard let data = try? event.serializedData() else {
Kinescope.shared.logger?.log(message: "Could not serialize event", level: KinescopeLoggerLevel.analytics)
return
}
executionQueue.async { [weak self] in
do {

let request = try RequestBuilder(path: "https://metrics.kinescope.io/player-native", method: .post)
let request = try RequestBuilder(path: path, method: .post)
.build(body: data)

self?.transport.performRaw(request: request, completion: { result in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ final class AnalyticsProxyService: AnalyticsService {
self.wrappedServices = wrappedServices
}

func send(event: Analytics_Native) {
wrappedServices.forEach { $0.send(event: event) }
func send(event: Analytics_Native, for video: KinescopeVideo) {
wrappedServices.forEach { $0.send(event: event, for: video) }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
import Foundation

protocol AnalyticsService {
func send(event: Analytics_Native)
func send(event: Analytics_Native, for video: KinescopeVideo)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
import Foundation

public protocol DataProtectionHandlerFactory {
func provide(for videoId: String) -> DataProtectionHandler?
func provide(for video: KinescopeVideo) -> DataProtectionHandler?
}

struct DefaultDataProtectionHandlerFactory: DataProtectionHandlerFactory {

let service: DataProtectionService

func provide(for videoId: String) -> DataProtectionHandler? {
func provide(for video: KinescopeVideo) -> DataProtectionHandler? {
if #available(iOS 11, *) {
return DataProtectionKeySessionHandler(videoId: videoId, service: service)
return DataProtectionKeySessionHandler(video: video, service: service)
} else {
return DataProtectionResourceDelegateHandler(videoId: videoId, service: service)
return DataProtectionResourceDelegateHandler(video: video, service: service)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ final class DataProtectionKeySessionHandler: NSObject, DataProtectionHandler {

// MARK: - Private Properties

private let videoId: String
private let video: KinescopeVideo
private let service: DataProtectionService
private lazy var session: AVContentKeySession = .init(keySystem: .fairPlayStreaming)

private let executionQueue = DispatchQueue(label: "io.kinescope.fairplay")

// MARK: - Lifecycle

init(videoId: String, service: DataProtectionService) {
self.videoId = videoId
init(video: KinescopeVideo, service: DataProtectionService) {
self.video = video
self.service = service
super.init()
}
Expand All @@ -49,7 +49,7 @@ extension DataProtectionKeySessionHandler: AVContentKeySessionDelegate {
return
}

service.getCert(for: videoId) { [weak self] result in
service.getCert(for: video) { [weak self] result in
guard let self else {
return
}
Expand Down Expand Up @@ -96,7 +96,7 @@ private extension DataProtectionKeySessionHandler {
return
}

guard let videoId = self?.videoId,
guard let videoId = self?.video,
let spc = spcData?.base64EncodedString() else {
self?.handleError(.cannotEncodeSPC, for: keyRequest)
return
Expand Down
Loading

0 comments on commit 8a52a34

Please sign in to comment.