Add audio and video codecs

This commit is contained in:
Benoit Martins 2025-01-21 11:56:06 +01:00
parent 10a400351a
commit 8ec47edf25
4 changed files with 156 additions and 12 deletions

View file

@ -104,6 +104,7 @@
D732A9152B04C7FE00DB42BA /* HistoryListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D732A9142B04C7FE00DB42BA /* HistoryListViewModel.swift */; };
D732A91B2B061BD900DB42BA /* HistoryListBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D732A91A2B061BD900DB42BA /* HistoryListBottomSheet.swift */; };
D732C38C2D311D2500F78100 /* SettingsFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D732C38B2D311D2100F78100 /* SettingsFragment.swift */; };
D7343FE82D3FA2000059D784 /* CodecModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7343FE72D3FA1F40059D784 /* CodecModel.swift */; };
D73449992BC6932A00778C56 /* MeetingWaitingRoomFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73449982BC6932A00778C56 /* MeetingWaitingRoomFragment.swift */; };
D734499B2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D734499A2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift */; };
D748BF2C2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */; };
@ -306,6 +307,7 @@
D732A9142B04C7FE00DB42BA /* HistoryListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryListViewModel.swift; sourceTree = "<group>"; };
D732A91A2B061BD900DB42BA /* HistoryListBottomSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryListBottomSheet.swift; sourceTree = "<group>"; };
D732C38B2D311D2100F78100 /* SettingsFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFragment.swift; sourceTree = "<group>"; };
D7343FE72D3FA1F40059D784 /* CodecModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodecModel.swift; sourceTree = "<group>"; };
D73449982BC6932A00778C56 /* MeetingWaitingRoomFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingWaitingRoomFragment.swift; sourceTree = "<group>"; };
D734499A2BC694C900778C56 /* MeetingWaitingRoomViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingWaitingRoomViewModel.swift; sourceTree = "<group>"; };
D748BF2B2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartySipAccountLoginFragment.swift; sourceTree = "<group>"; };
@ -952,6 +954,7 @@
D7DC096C2CFA193B00A6D47C /* Models */ = {
isa = PBXGroup;
children = (
D7343FE72D3FA1F40059D784 /* CodecModel.swift */,
);
path = Models;
sourceTree = "<group>";
@ -1312,6 +1315,7 @@
D7DA67642ACCB31700E95002 /* ProfileModeFragment.swift in Sources */,
D7CEE03D2B7A23B200FD79B7 /* ConversationsListFragment.swift in Sources */,
D74C9CFC2ACACF370021626A /* WelcomePage3Fragment.swift in Sources */,
D7343FE82D3FA2000059D784 /* CodecModel.swift in Sources */,
D77A080E2CB6BCAF0095D589 /* MessageConferenceInfo.swift in Sources */,
C6A5A9412C10B5D50070FEA4 /* EncodableExtension.swift in Sources */,
D719ABCC2ABC769C00B41C10 /* AssistantView.swift in Sources */,

View file

@ -300,7 +300,7 @@ struct SettingsAdvancedFragment: View {
.transition(.move(edge: .top))
}
*/
/*
HStack(alignment: .center) {
Text("settings_advanced_audio_codecs_title")
.default_text_style_800(styleSize: 18)
@ -327,14 +327,14 @@ struct SettingsAdvancedFragment: View {
if audioCodecsIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
Toggle("settings_calls_adaptive_rate_control_title", isOn: $settingsViewModel.adaptiveRateControl)
.default_text_style_700(styleSize: 15)
Toggle("settings_calls_enable_video_title", isOn: $settingsViewModel.enableVideo)
.default_text_style_700(styleSize: 15)
Toggle("settings_calls_auto_record_title", isOn: $settingsViewModel.autoRecord)
.default_text_style_700(styleSize: 15)
ForEach(settingsViewModel.audioCodecs) { audioCodec in
SettingsToggleWidget(title: audioCodec.mimeType, subtitle: audioCodec.subtitle, isOn: Binding(
get: { audioCodec.isEnabled },
set: { newValue in
audioCodec.toggleEnabled()
}
))
}
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
@ -372,8 +372,14 @@ struct SettingsAdvancedFragment: View {
if videoCodecsIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
Toggle("settings_conversations_auto_download_title", isOn: $settingsViewModel.autoDownload)
.default_text_style_700(styleSize: 15)
ForEach(settingsViewModel.videoCodecs) { videoCodec in
SettingsToggleWidget(title: videoCodec.mimeType, subtitle: videoCodec.subtitle, isOn: Binding(
get: { videoCodec.isEnabled },
set: { newValue in
videoCodec.toggleEnabled()
}
))
}
}
.padding(.vertical, 30)
.padding(.horizontal, 20)
@ -384,7 +390,6 @@ struct SettingsAdvancedFragment: View {
.zIndex(-3)
.transition(.move(edge: .top))
}
*/
}
}
.background(Color.gray100)
@ -395,3 +400,29 @@ struct SettingsAdvancedFragment: View {
.navigationBarHidden(true)
}
}
struct SettingsToggleWidget: View {
var title: String
var subtitle: String
@Binding var isOn: Bool
var body: some View {
HStack {
VStack(alignment: .leading, spacing: 2) {
Text(title)
.default_text_style_700(styleSize: 15)
if !subtitle.isEmpty {
Text(subtitle)
.foregroundColor(Color.grayMain2c500)
.default_text_style(styleSize: 14)
}
}
.layoutPriority(1)
Toggle(isOn: $isOn) {
EmptyView()
}
.toggleStyle(SwitchToggleStyle())
}
}
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import Foundation
class CodecModel: ObservableObject, Identifiable {
let id = UUID()
let mimeType: String
let clockRate: Int
let channels: Int
let recvFmtp: String?
let isAudioCodec: Bool
private let onEnabledChanged: (Bool) -> Void
@Published var isEnabled: Bool
@Published var subtitle: String
init(
mimeType: String,
clockRate: Int,
channels: Int,
recvFmtp: String?,
isAudioCodec: Bool,
enabled: Bool,
onEnabledChanged: @escaping (Bool) -> Void
) {
self.mimeType = mimeType
self.clockRate = clockRate
self.channels = channels
self.recvFmtp = recvFmtp
self.isAudioCodec = isAudioCodec
self.isEnabled = enabled
self.onEnabledChanged = onEnabledChanged
if isAudioCodec {
self.subtitle = "\(clockRate) Hz" + (isAudioCodec ? " (\(channels == 1 ? "Mono" : "Stereo"))" : "")
} else {
self.subtitle = recvFmtp ?? ""
}
}
func toggleEnabled() {
let newValue = !isEnabled
onEnabledChanged(newValue)
isEnabled = newValue
}
}

View file

@ -62,6 +62,9 @@ class SettingsViewModel: ObservableObject {
@Published var outputAudioDeviceValues: [AudioDevice] = []
@Published var outputAudioDeviceIndex: Int = 0
@Published var audioCodecs: [CodecModel] = []
@Published var videoCodecs: [CodecModel] = []
init() {
CoreContext.shared.doOnCoreQueue { core in
@ -136,6 +139,8 @@ class SettingsViewModel: ObservableObject {
)
core.addDelegate(delegate: self.coreDelegate!)
*/
self.setupCodecs()
}
}
}
@ -249,6 +254,47 @@ class SettingsViewModel: ObservableObject {
}
}
func setupCodecs() {
CoreContext.shared.doOnCoreQueue { core in
var audioCodecsList: [CodecModel] = []
for payload in core.audioPayloadTypes {
let model = CodecModel(
mimeType: payload.mimeType,
clockRate: payload.clockRate,
channels: payload.channels,
recvFmtp: nil,
isAudioCodec: true,
enabled: payload.enabled(),
onEnabledChanged: { enabled in
payload.enable(enabled: enabled)
}
)
audioCodecsList.append(model)
}
var videoCodecsList: [CodecModel] = []
for payload in core.videoPayloadTypes {
let model = CodecModel(
mimeType: payload.mimeType,
clockRate: -1,
channels: -1,
recvFmtp: payload.recvFmtp,
isAudioCodec: false,
enabled: payload.enabled(),
onEnabledChanged: { enabled in
payload.enable(enabled: enabled)
}
)
videoCodecsList.append(model)
}
DispatchQueue.main.async {
self.audioCodecs = audioCodecsList
self.videoCodecs = videoCodecsList
}
}
}
func saveChangesWhenLeaving() {
CoreContext.shared.doOnCoreQueue { core in
if CorePreferences.vfsEnabled != self.enableVfs {