Skip to content

Commit

Permalink
Add metrics collector (#916)
Browse files Browse the repository at this point in the history
  • Loading branch information
defagos authored Jun 20, 2024
1 parent 00e471d commit ba03312
Show file tree
Hide file tree
Showing 17 changed files with 888 additions and 17 deletions.
40 changes: 40 additions & 0 deletions Demo/Pillarbox-demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
6F0E5CD52B33A41F0031E313 /* MonoscopicVideoView~ios.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F0E5CD42B33A41F0031E313 /* MonoscopicVideoView~ios.swift */; };
6F12A9522BD2B8A300AD6DDB /* IntegratingWithControlCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F12A9512BD2B8A300AD6DDB /* IntegratingWithControlCenter.swift */; };
6F26F35E2B33B73900392ED4 /* SupportingBasicPictureInPicture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F26F35D2B33B73900392ED4 /* SupportingBasicPictureInPicture.swift */; };
6F56F91F2C1D85F800495E20 /* MetricsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F56F91E2C1D85F600495E20 /* MetricsView.swift */; };
6F56F9232C1D893400495E20 /* ObservedBitrateChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F56F9222C1D892800495E20 /* ObservedBitrateChart.swift */; };
6F56F9252C1D89FC00495E20 /* IndicatedBitrateChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F56F9242C1D89F700495E20 /* IndicatedBitrateChart.swift */; };
6F56F9272C1D8A2E00495E20 /* MediaRequestChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F56F9262C1D8A2000495E20 /* MediaRequestChart.swift */; };
6F59E87929CF31E10093E6FB /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F59E84029CF31E10093E6FB /* SearchView.swift */; };
6F59E87A29CF31E10093E6FB /* SearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F59E84129CF31E10093E6FB /* SearchViewModel.swift */; };
6F59E87B29CF31E10093E6FB /* DemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F59E84329CF31E10093E6FB /* DemoApp.swift */; };
Expand Down Expand Up @@ -72,6 +76,10 @@
6F59E8A329CF31E20093E6FB /* ExamplesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F59E87729CF31E10093E6FB /* ExamplesView.swift */; };
6F59E8A429CF31E20093E6FB /* ExamplesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F59E87829CF31E10093E6FB /* ExamplesViewModel.swift */; };
6F6643D92A61140600BFD644 /* URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F6643D82A61140600BFD644 /* URL.swift */; };
6F7DDB5D2C1FFF2600B48A67 /* MetricsInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7DDB5C2C1FFF0500B48A67 /* MetricsInfoView.swift */; };
6F7DDB5F2C20360F00B48A67 /* StallsChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7DDB5E2C20360B00B48A67 /* StallsChart.swift */; };
6F7DDB612C20388800B48A67 /* FrameDropsChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7DDB602C20388200B48A67 /* FrameDropsChart.swift */; };
6F7DDB632C20395100B48A67 /* DataVolumeChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7DDB622C20394600B48A67 /* DataVolumeChart.swift */; };
6F7EAA552B17755C00194D03 /* TrackingProgressTutorial~ios.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7EAA542B17755C00194D03 /* TrackingProgressTutorial~ios.swift */; };
6F8459F22A38543400A7B5F2 /* Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8459F12A38543400A7B5F2 /* Signal.swift */; };
6F8600FC2B358BC0005CBCC5 /* SRGMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8600FB2B358BC0005CBCC5 /* SRGMedia.swift */; };
Expand Down Expand Up @@ -127,6 +135,10 @@
6F45DB9D2893B773008ACCE6 /* Demo.nightly.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Demo.nightly.xcconfig; sourceTree = "<group>"; };
6F45DB9E2893B773008ACCE6 /* Demo.debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Demo.debug.xcconfig; sourceTree = "<group>"; };
6F45DB9F2893B773008ACCE6 /* Demo.release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Demo.release.xcconfig; sourceTree = "<group>"; };
6F56F91E2C1D85F600495E20 /* MetricsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetricsView.swift; sourceTree = "<group>"; };
6F56F9222C1D892800495E20 /* ObservedBitrateChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservedBitrateChart.swift; sourceTree = "<group>"; };
6F56F9242C1D89F700495E20 /* IndicatedBitrateChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndicatedBitrateChart.swift; sourceTree = "<group>"; };
6F56F9262C1D8A2000495E20 /* MediaRequestChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaRequestChart.swift; sourceTree = "<group>"; };
6F59E84029CF31E10093E6FB /* SearchView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = "<group>"; };
6F59E84129CF31E10093E6FB /* SearchViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchViewModel.swift; sourceTree = "<group>"; };
6F59E84329CF31E10093E6FB /* DemoApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoApp.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -170,6 +182,10 @@
6F59E87829CF31E10093E6FB /* ExamplesViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExamplesViewModel.swift; sourceTree = "<group>"; };
6F6643D82A61140600BFD644 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = "<group>"; };
6F7A2B252A707708005701C7 /* pillarbox-apple */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "pillarbox-apple"; path = ..; sourceTree = "<group>"; };
6F7DDB5C2C1FFF0500B48A67 /* MetricsInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetricsInfoView.swift; sourceTree = "<group>"; };
6F7DDB5E2C20360B00B48A67 /* StallsChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StallsChart.swift; sourceTree = "<group>"; };
6F7DDB602C20388200B48A67 /* FrameDropsChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrameDropsChart.swift; sourceTree = "<group>"; };
6F7DDB622C20394600B48A67 /* DataVolumeChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataVolumeChart.swift; sourceTree = "<group>"; };
6F7EAA542B17755C00194D03 /* TrackingProgressTutorial~ios.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TrackingProgressTutorial~ios.swift"; sourceTree = "<group>"; };
6F8459F12A38543400A7B5F2 /* Signal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signal.swift; sourceTree = "<group>"; };
6F8600FB2B358BC0005CBCC5 /* SRGMedia.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRGMedia.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -277,6 +293,21 @@
path = Application;
sourceTree = "<group>";
};
6F56F91D2C1D85E900495E20 /* Metrics */ = {
isa = PBXGroup;
children = (
6F7DDB622C20394600B48A67 /* DataVolumeChart.swift */,
6F7DDB602C20388200B48A67 /* FrameDropsChart.swift */,
6F56F9242C1D89F700495E20 /* IndicatedBitrateChart.swift */,
6F56F9262C1D8A2000495E20 /* MediaRequestChart.swift */,
6F7DDB5C2C1FFF0500B48A67 /* MetricsInfoView.swift */,
6F56F91E2C1D85F600495E20 /* MetricsView.swift */,
6F56F9222C1D892800495E20 /* ObservedBitrateChart.swift */,
6F7DDB5E2C20360B00B48A67 /* StallsChart.swift */,
);
path = Metrics;
sourceTree = "<group>";
};
6F59E83F29CF31E10093E6FB /* Search */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -502,6 +533,7 @@
6F59E84D29CF31E10093E6FB /* ContentLists */,
6F59E87629CF31E10093E6FB /* Examples */,
6F6643D72A6113F300BFD644 /* Extensions */,
6F56F91D2C1D85E900495E20 /* Metrics */,
6F59E84529CF31E10093E6FB /* Model */,
6F59E86929CF31E10093E6FB /* Players */,
6F0B2E832A40EB9600B69675 /* Router */,
Expand Down Expand Up @@ -626,15 +658,19 @@
0EE2A3AE2B29D6D000BAAD65 /* CustomList.swift in Sources */,
6F59E87C29CF31E10093E6FB /* AppDelegate.swift in Sources */,
0E011D1A2B2DF9BE00DAAD3D /* MediaCardView.swift in Sources */,
6F7DDB612C20388800B48A67 /* FrameDropsChart.swift in Sources */,
6FAD51122B331A370078FE08 /* MultiViewModel.swift in Sources */,
6F59E88E29CF31E20093E6FB /* StoriesViewModel.swift in Sources */,
6F59E89729CF31E20093E6FB /* MessageViews.swift in Sources */,
6F56F9252C1D89FC00495E20 /* IndicatedBitrateChart.swift in Sources */,
6F59E88C29CF31E20093E6FB /* TwinsView.swift in Sources */,
6FC5D6A42A6FACB20012BC89 /* CloseButton.swift in Sources */,
6F59E88529CF31E20093E6FB /* ContentListsView.swift in Sources */,
6F59E8A329CF31E20093E6FB /* ExamplesView.swift in Sources */,
6F56F91F2C1D85F800495E20 /* MetricsView.swift in Sources */,
0E6B995C29D43E4200D0276D /* OptInView.swift in Sources */,
6F59E89C29CF31E20093E6FB /* BasicPlaybackView.swift in Sources */,
6F7DDB5F2C20360F00B48A67 /* StallsChart.swift in Sources */,
0EDFF0DB2B0740DA005030B4 /* SourceCodeViewable.swift in Sources */,
6F59E87A29CF31E10093E6FB /* SearchViewModel.swift in Sources */,
6F59E88829CF31E20093E6FB /* UserDefaults.swift in Sources */,
Expand All @@ -654,6 +690,7 @@
6FF7C9852C0084CE00FBDADB /* PlaybackHudColor.swift in Sources */,
6F59E88229CF31E10093E6FB /* Media.swift in Sources */,
6FF7C9872C0084DD00FBDADB /* SeekBehaviorSetting.swift in Sources */,
6F7DDB5D2C1FFF2600B48A67 /* MetricsInfoView.swift in Sources */,
6F59E87E29CF31E10093E6FB /* ServerSetting.swift in Sources */,
6F59E87929CF31E10093E6FB /* SearchView.swift in Sources */,
6F59E88029CF31E10093E6FB /* RadioChannel.swift in Sources */,
Expand Down Expand Up @@ -682,13 +719,16 @@
6F8600FC2B358BC0005CBCC5 /* SRGMedia.swift in Sources */,
6F59E88429CF31E20093E6FB /* ContentListViewModel.swift in Sources */,
6F59E88329CF31E20093E6FB /* MediaDescription.swift in Sources */,
6F56F9272C1D8A2E00495E20 /* MediaRequestChart.swift in Sources */,
6F59E8A429CF31E20093E6FB /* ExamplesViewModel.swift in Sources */,
6F59E89829CF31E20093E6FB /* PlayerConfiguration.swift in Sources */,
6F8459F22A38543400A7B5F2 /* Signal.swift in Sources */,
6FDB51CB2A4042B2001F430F /* Router.swift in Sources */,
6F59E88B29CF31E20093E6FB /* PlaylistViewModel.swift in Sources */,
6F56F9232C1D893400495E20 /* ObservedBitrateChart.swift in Sources */,
6F59E87F29CF31E10093E6FB /* Template.swift in Sources */,
6F0B2E8B2A40EE0700B69675 /* ContentList.swift in Sources */,
6F7DDB632C20395100B48A67 /* DataVolumeChart.swift in Sources */,
6F0B2E852A40EBAC00B69675 /* RouterDestination.swift in Sources */,
6FCB9DDE29E024E900961B69 /* BlurredView.swift in Sources */,
6F59E89129CF31E20093E6FB /* WrappedView.swift in Sources */,
Expand Down
69 changes: 69 additions & 0 deletions Demo/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@
},
"Continues if possible" : {

},
"Curr. %.02f Mbps" : {

},
"Data volume" : {

},
"Data volume (MB)" : {

},
"Debugging" : {

Expand All @@ -114,18 +123,33 @@
},
"Font size" : {

},
"Frame drops" : {

},
"GitHub" : {

},
"Green" : {

},
"Hide" : {

},
"Immediate" : {

},
"Improves playlist navigation so that it feels more natural." : {

},
"Index" : {

},
"Indicated bitrate" : {

},
"Indicated bitrate (Mbps)" : {

},
"Kind" : {

Expand All @@ -144,12 +168,45 @@
},
"Made with " : {

},
"Max. %.02f Mbps" : {

},
"MB" : {

},
"Mbps" : {

},
"Media requests" : {

},
"Metrics" : {
"comment" : "Playback setting menu title"
},
"Min. %.02f Mbps" : {

},
"Mode" : {

},
"No metrics" : {

},
"None" : {

},
"Observed bitrate" : {

},
"Observed bitrate (Mbps)" : {

},
"Observed bitrate max" : {

},
"Observed bitrate min" : {

},
"Opt-in features" : {

Expand Down Expand Up @@ -198,6 +255,9 @@
},
"Settings" : {

},
"Show metrics" : {

},
"Showcase" : {

Expand All @@ -222,6 +282,9 @@
},
"SRG SSR token protection" : {

},
"Stalls" : {

},
"Stop" : {

Expand All @@ -240,6 +303,12 @@
},
"Top" : {

},
"Total %@" : {

},
"Total %lld" : {

},
"Tracking" : {

Expand Down
47 changes: 47 additions & 0 deletions Demo/Sources/Metrics/DataVolumeChart.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// Copyright (c) SRG SSR. All rights reserved.
//
// License information is available from the LICENSE file.
//

import Charts
import PillarboxPlayer
import SwiftUI

struct DataVolumeChart: View {
let metrics: [Metrics]
let limit: Int

var body: some View {
chart()
summary()
}

private var bytesTransferred: String {
ByteCountFormatStyle().format(metrics.last?.total.numberOfBytesTransferred ?? 0)
}

@ViewBuilder
private func chart() -> some View {
Chart(Array(metrics.suffix(limit).enumerated()), id: \.offset) { metrics in
BarMark(
x: .value("Index", metrics.offset),
y: .value("Data volume (MB)", metrics.element.increment.numberOfBytesTransferred / 1_000_000),
width: .inset(1)
)
.foregroundStyle(.cyan)
}
.chartXAxis(.hidden)
.chartXScale(domain: 0...limit - 1)
.chartYAxisLabel("MB")
.padding(.vertical)
}

@ViewBuilder
private func summary() -> some View {
Text("Total \(bytesTransferred)")
.font(.caption2)
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity, alignment: .center)
}
}
46 changes: 46 additions & 0 deletions Demo/Sources/Metrics/FrameDropsChart.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// Copyright (c) SRG SSR. All rights reserved.
//
// License information is available from the LICENSE file.
//

import Charts
import PillarboxPlayer
import SwiftUI

struct FrameDropsChart: View {
let metrics: [Metrics]
let limit: Int

var body: some View {
chart()
summary()
}

private var total: Int {
metrics.last?.total.numberOfDroppedVideoFrames ?? 0
}

@ViewBuilder
private func chart() -> some View {
Chart(Array(metrics.suffix(limit).enumerated()), id: \.offset) { metrics in
BarMark(
x: .value("Index", metrics.offset),
y: .value("Frame drops", metrics.element.increment.numberOfDroppedVideoFrames),
width: .inset(1)
)
.foregroundStyle(.purple)
}
.chartXAxis(.hidden)
.chartXScale(domain: 0...limit - 1)
.padding(.vertical)
}

@ViewBuilder
private func summary() -> some View {
Text("Total \(total)")
.font(.caption2)
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity, alignment: .center)
}
}
Loading

0 comments on commit ba03312

Please sign in to comment.