Friday Commit

This commit is contained in:
Bilal
2024-07-15 00:43:25 +05:30
parent 6a96b87465
commit 999b643d3c
5 changed files with 517 additions and 139 deletions

View File

@@ -233,6 +233,7 @@
9C834ED72C1C1F9200B29A9C /* Exo2-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8332BDBC3EF00E4CA14 /* Exo2-Regular.ttf */; };
9C834ED82C1C1F9200B29A9C /* Exo2-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8312BDBC3EF00E4CA14 /* Exo2-Thin.ttf */; };
9C834EDC2C1C26CD00B29A9C /* HtmlText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C834EDB2C1C26CD00B29A9C /* HtmlText.swift */; };
9C8446872C40FC6E003E3E53 /* AVPlayerTesting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C8446862C40FC6E003E3E53 /* AVPlayerTesting.swift */; };
9C8C4FAE2C1315410017DD3B /* WebViewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C8C4FAD2C1315410017DD3B /* WebViewVC.swift */; };
9C8C4FB02C1328060017DD3B /* Disclaimer.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 9C8C4FAF2C1328060017DD3B /* Disclaimer.rtf */; };
9C9BEEC72BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C9BEEC62BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift */; };
@@ -505,6 +506,7 @@
9C834EC52C1C1D9500B29A9C /* BlogDetailsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogDetailsVC.swift; sourceTree = "<group>"; };
9C834ED92C1C20EC00B29A9C /* WOKA.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WOKA.entitlements; sourceTree = "<group>"; };
9C834EDB2C1C26CD00B29A9C /* HtmlText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HtmlText.swift; sourceTree = "<group>"; };
9C8446862C40FC6E003E3E53 /* AVPlayerTesting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayerTesting.swift; sourceTree = "<group>"; };
9C8C4FAD2C1315410017DD3B /* WebViewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewVC.swift; sourceTree = "<group>"; };
9C8C4FAF2C1328060017DD3B /* Disclaimer.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Disclaimer.rtf; sourceTree = "<group>"; };
9C9BEEC62BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewCenteredFlowLayout.swift; sourceTree = "<group>"; };
@@ -1391,6 +1393,7 @@
52F4E8652C3D123B00778FBC /* JWKaraokePlayerVC.swift */,
525FC61C2C3D3DC30049145D /* AVAssetMods.swift */,
525FC65C2C3D57D80049145D /* TestingKaraokeVC.swift */,
9C8446862C40FC6E003E3E53 /* AVPlayerTesting.swift */,
);
path = Controller;
sourceTree = "<group>";
@@ -1764,6 +1767,7 @@
52BC3BF02C1701F8002FACA6 /* BlogDM.swift in Sources */,
525954192BE8CC3400191286 /* ConstantString.swift in Sources */,
52D774EB2BDFC0BF001D87DE /* OTPVC.swift in Sources */,
9C8446872C40FC6E003E3E53 /* AVPlayerTesting.swift in Sources */,
52AF71F42C36C40B00BC5972 /* GamesWebViewVC.swift in Sources */,
9C007F202C255DF200F798C2 /* SeasonEpisodeListingDM.swift in Sources */,
52D2F3D82C24043D009E52FF /* ShimmerEffectView.swift in Sources */,

View File

@@ -0,0 +1,22 @@
//
// AVPlayerTesting.swift
// WOKA
//
// Created by Bilal on 12/07/2024.
//
import UIKit
import AVKit
class AVPlayerTesting: AVPlayerViewController {
override func viewDidLoad() {
super.viewDidLoad()
let videoURL = URL(string: "https://content.jwplatform.com/videos/699dmCGz-Ysj2G4DQ.mp4")!
let player = AVPlayer(url: videoURL)
self.player = player
player.play()
// Do any additional setup after loading the view.
}
}

View File

@@ -12,56 +12,65 @@ import AVFoundation
class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
@IBOutlet weak var outerStack: UIStackView!
@IBOutlet weak var backButton: UIButton!
@IBOutlet weak var startRecordBtn: LocalisedElementsButton!
@IBOutlet weak var playBtn: LocalisedElementsButton!
@IBOutlet weak var downloadRecordingBtn: LocalisedElementsButton!
@IBOutlet weak var karaokeStack: UIStackView!
@IBOutlet weak var karaokeLoading: UIActivityIndicatorView!
@IBOutlet weak var startStopRecordingStack: UIStackView!
@IBOutlet weak var outerStack : UIStackView!
var config: JWPlayerConfiguration!
var dismissTapped: (() -> Void)?
var videoIndex : Int?
var documentAudioUrl : URL?
var audioURLFromMP4 : URL?
var recordedAudioURL: URL?
var audioRecorder: AVAudioRecorder?
var videoTitle : String?
var videoUrl : String?
var mixedAudioURL: URL?
var isRecording = false
var playerAV : AVAudioPlayer?
var isPlaying = false
var mixedAudioURL: URL? {
didSet{
do{
let sPlayer = try AVAudioPlayer(contentsOf: self.mixedAudioURL!)
self.playerAV = sPlayer
self.playerAV?.prepareToPlay()
// self.playerAV?.play()
}catch{
}
}
}
var startTime : TimeInterval?
var endTime : TimeInterval?
var audioPlayer = AVPlayer()
override func viewDidLoad() {
super.viewDidLoad()
player.configurePlayer(with: config)
self.delegate = self
//Disable Picture in Picture
playerView.allowsPictureInPicturePlayback = false
playerView.captionStyle = .none
self.view.bringSubviewToFront(outerStack)
self.view.bringSubviewToFront(backButton)
setupRecorder()
setupKaraoke()
}
func setupRecorder(){
// MARK: - AudioRecording
func setupAudio() {
// FileManager.default.clearTmpDirectory()
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.playAndRecord, mode: .default,options: .defaultToSpeaker)
try audioSession.setActive(true)
// // URL of the downloaded M4A file
// guard let audioURL = Bundle.main.url(forResource: "Sample_audio", withExtension: "m4a") else {
// print("Audio file not found.")
// return
// }
// Initialize AVAudioPlayer with the downloaded M4A file
// player = try AVAudioPlayer(contentsOf: audioURLFromMP4!)
// player?.prepareToPlay()
// Define settings for the audio recorder
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
@@ -83,63 +92,148 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
}
func startRecording() {
guard let player = player, let audioRecorder = audioRecorder else { return }
player.play()
startTime = self.player.time.position.round(to: 1)
self.interfaceBehavior = .hidden
guard let audioRecorder = audioRecorder else { return }
audioRecorder.record()
}
func stopRecording() {
guard let player = player, let audioRecorder = audioRecorder else { return }
player.pause() // Pause playback instead of stopping it
endTime = self.player.time.position.round(to: 1)
self.interfaceBehavior = .normal
guard let audioRecorder = audioRecorder else { return }
audioRecorder.stop()
self.player.pause()
// Mix the recorded audio with the downloaded M4A file
mixAudio()
guard let startTime , let endTime else{return}
mixAudio(start: startTime, stop: endTime)
}
func mixAudio() {
func mixAudio(start : TimeInterval, stop : TimeInterval) {
let totalTime = stop - start
guard let recordedAudioURL = recordedAudioURL else { return }
// guard let playerURL = Bundle.main.url(forResource: "Sample_audio", withExtension: "m4a") else { return }
guard let playerURL = documentAudioUrl else{return}
guard let playerURL = audioURLFromMP4 else { return }
Utilities.startProgressHUD(msg: "Mixing Audio")
let composition = AVMutableComposition()
let compositionDuration = CMTime(seconds: totalTime, preferredTimescale: 1)
// Add the recorded audio
// Add the recorded audio from 0 to 10 seconds
let recordedAudioAsset = AVURLAsset(url: recordedAudioURL)
let recordedAudioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
do {
try recordedAudioTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: recordedAudioAsset.duration), of: recordedAudioAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
try recordedAudioTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: compositionDuration), of: recordedAudioAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
} catch {
Utilities.dismissProgressHUD()
print("Error adding recorded audio track: \(error.localizedDescription)")
}
// Add the downloaded M4A file
// Add the downloaded M4A file from 10 to 20 seconds
let playerAsset = AVURLAsset(url: playerURL)
let playerTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
do {
try playerTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: playerAsset.duration), of: playerAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
try playerTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime(seconds: start, preferredTimescale: 1), duration: compositionDuration), of: playerAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
} catch {
Utilities.dismissProgressHUD()
print("Error adding player audio track: \(error.localizedDescription)")
}
// Example usage:
// Export the mixed audio
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
mixedAudioURL = documentsDirectory.appendingPathComponent("mixedAudio.m4a")
let filePath = documentsDirectory.appendingPathComponent("mixedAudio.m4a")
deleteFileIfExist(at: filePath)
mixedAudioURL = filePath
// mixedAudioURL = documentsDirectory.appendingPathComponent("mixedAudio.m4a")
guard let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A) else { return }
exportSession.outputURL = mixedAudioURL
exportSession.outputFileType = .m4a
exportSession.exportAsynchronously {
if exportSession.status == .completed {
print("Mixing audio completed.")
Utilities.dismissProgressHUD()
DispatchQueue.main.async {
self.playBtn.isEnabled = true
}
self.saveToFilesApp()
// Play the mixed audio if needed
} else if exportSession.status == .failed {
print("Mixing audio failed.")
print("Mixing audio failed.", exportSession.error?.localizedDescription)
}
}
}
func deleteFileIfExist(at url: URL) {
let fileManager = FileManager.default
do {
// Check if the file exists
if fileManager.fileExists(atPath: url.path) {
// Attempt to delete the file
try fileManager.removeItem(at: url)
print("File deleted successfully.")
} else {
print("File does not exist at path: \(url.path)")
}
} catch {
print("Error deleting file: \(error.localizedDescription)")
}
}
// func mixAudio() {
// guard let recordedAudioURL = recordedAudioURL else { return }
// guard let playerURL = audioURLFromMP4 else{return}
// let composition = AVMutableComposition()
//
// // Add the recorded audio
// let recordedAudioAsset = AVURLAsset(url: recordedAudioURL)
// let recordedAudioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
// do {
// try recordedAudioTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: recordedAudioAsset.duration), of: recordedAudioAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
// } catch {
// print("Error adding recorded audio track: \(error.localizedDescription)")
// }
//
// // Add the downloaded M4A file
// let playerAsset = AVURLAsset(url: playerURL)
// let playerTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
//
// do {
// try playerTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: playerAsset.duration), of: playerAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
// } catch {
// print("Error adding player audio track: \(error.localizedDescription)")
// }
//
// // Export the mixed audio
// let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// mixedAudioURL = documentsDirectory.appendingPathComponent("mixedAudio.m4a")
// guard let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A) else { return }
// exportSession.outputURL = mixedAudioURL
// exportSession.outputFileType = .m4a
// exportSession.exportAsynchronously {
// if exportSession.status == .completed {
// print("Mixing audio completed.")
//
// self.saveToFilesApp()
// // Play the mixed audio if needed
//
//
// } else if exportSession.status == .failed {
// print("Mixing audio failed.")
// }
// }
// }
func saveToFilesApp() {
guard let mixedAudioURL = mixedAudioURL else { return }
DispatchQueue.main.async {
@@ -149,6 +243,40 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
}
}
func setupKaraoke(){
guard let videoUrl else{return}
let avURL = URL(string: videoUrl)!
let asset = AVAsset(url: avURL)
hideShowKaraoke(isLoading: true)
let outputURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(videoTitle?.trimmingCharacters(in: .whitespaces) ?? "extractedAudio").m4a")
FileManager.default.clearTmpDirectory()
asset.writeAudioTrackToURL(outputURL) { [weak self] isDone, error,url in
guard let self else{return}
print(isDone, error , url)
if error == nil{
hideShowKaraoke(isLoading: false)
self.audioURLFromMP4 = url
self.setupAudio()
}
}
}
func hideShowKaraoke(isLoading : Bool){
DispatchQueue.main.async { [weak self] in
guard let self else{return}
if isLoading{
karaokeLoading.startAnimating()
karaokeStack.isHidden = false
startStopRecordingStack.isHidden = true
}else{
karaokeLoading.stopAnimating()
karaokeLoading.hidesWhenStopped = true
karaokeStack.isHidden = true
startStopRecordingStack.isHidden = false
}
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// self.navigationController?.isNavigationBarHidden = true
@@ -160,20 +288,13 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
}
@IBAction func startRecordingBtnTapped(_ sender: LocalisedElementsButton) {
// if sender.titleLabel?.text?.lowercased() == "start recording"{
// guard let audioRecorder else { return }
// startRecordBtn.setTitle("Stop Recording", for: .normal)
// audioRecorder.record()
// }else{
// guard let audioRecorder else { return }
// startRecordBtn.setTitle("Stop Recording", for: .normal)
// audioRecorder.record()
// }
self.playBtn.isEnabled = false
if isRecording {
stopRecording()
self.interfaceBehavior = .normal
sender.setTitle("Start Recording", for: .normal)
} else {
self.interfaceBehavior = .hidden
startRecording()
sender.setTitle("Stop Recording", for: .normal)
}
@@ -181,12 +302,57 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
}
@IBAction func playBtnTapped(_ sender: LocalisedElementsButton) {
playerAV?.play()
if !isPlaying {
playMixedAudio()
self.interfaceBehavior = .normal
self.interfaceBehavior = .hidden
sender.setTitle("Pause", for: .normal)
} else {
self.interfaceBehavior = .normal
sender.setTitle("Play", for: .normal)
}
isPlaying.toggle()
self.player.pause()
print("Play")
}
func playMixedAudio() {
guard let mixedAudioURL = mixedAudioURL else { return }
do {
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationURL = documentsDirectoryURL.appendingPathComponent("xyze.m4a")
do {
try FileManager.default.copyItem(at: mixedAudioURL, to: destinationURL)
} catch
let error as NSError { print(error.localizedDescription)}
let playerKAraoke = AVPlayer(url: destinationURL)
playerKAraoke.volume = 1.0
playerKAraoke.play()
// // Configure the audio session
// let audioSession = AVAudioSession.sharedInstance()
// try audioSession.setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker])
// try audioSession.setActive(true)
//
// let audioPlayer = try AVAudioPlayer(contentsOf: mixedAudioURL)
// audioPlayer.volume = 1.0
// audioPlayer.play()
} catch {
print("Error playing mixed audio: \(error.localizedDescription)")
}
}
@IBAction func downloadRecording(_ sender: LocalisedElementsButton) {
print("DownloadRecording")
self.saveToFilesApp()
}
@IBAction func backBtnTapped(_ sender: UIButton) {
self.player.stop()
@@ -259,8 +425,29 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
}
extension JWKaraokePlayerVC: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
// Handle document picking completion if needed
deleteTemporaryFile()
// guard let selectedURL = urls.first else { return }
// do {
// try FileManager.default.moveItem(at: fileURL, to: selectedURL)
// } catch {
// print("Error saving file to Files app: \(error)")
// }
}
// Method to delete the temporary file
func deleteTemporaryFile() {
let tempFileURL = audioURLFromMP4!
do {
try FileManager.default.removeItem(at: tempFileURL)
print("Temporary file deleted successfully.")
} catch {
print("Error deleting temporary file: \(error.localizedDescription)")
}
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
print("Document picker was cancelled")
}
}
// MARK: - Full Screen Handling
@@ -350,3 +537,96 @@ extension JWKaraokePlayerVC {
print("Item ", item)
}
}
//OLD Code
//private var audioEngine: AVAudioEngine!
// private var audioFile: AVAudioFile!
// private var audioPlayerNode: AVAudioPlayerNode!
// private var recordedAudioFile: AVAudioFile!
//private var recordingURL: URL!
//
//private func setupAudioEngine() {
// audioEngine = AVAudioEngine()
// audioPlayerNode = AVAudioPlayerNode()
//
// audioEngine.attach(audioPlayerNode)
// let format = audioEngine.mainMixerNode.outputFormat(forBus: 0)
// audioEngine.connect(audioPlayerNode, to: audioEngine.mainMixerNode, format: format)
//}
//
//private func startRecording() {
// let format = audioEngine.mainMixerNode.outputFormat(forBus: 0)
// let outputFileURL = FileManager.default.temporaryDirectory.appendingPathComponent("savedRecordedAudio.m4a")
// recordingURL = outputFileURL
//
// do {
// recordedAudioFile = try AVAudioFile(forWriting: outputFileURL, settings: format.settings)
// } catch {
// print("Error creating audio file for recording: \(error)")
// return
// }
//
// audioEngine.mainMixerNode.installTap(onBus: 0, bufferSize: 1024, format: format) { (buffer, time) in
// do {
// try self.recordedAudioFile?.write(from: buffer)
// } catch {
// print("Error writing audio buffer: \(error)")
// }
// }
//
// do {
// try audioEngine.start()
// } catch {
// print("Error starting audio engine: \(error)")
// return
// }
//
// audioPlayerNode.play()
//}
//
//private func stopRecording() {
// audioEngine.mainMixerNode.removeTap(onBus: 0)
// audioPlayerNode.stop()
// audioEngine.stop()
// guard let mixedAudioURL = recordingURL else { return }
// playAudio(at: mixedAudioURL)
//// presentDocumentPicker()
// }
//
//private func playAudio(at url: URL) {
// do {
// let audioPlayer = try AVAudioPlayer(contentsOf: url)
// audioPlayer.play()
// } catch {
// print("Error playing audio: \(error)")
// }
//}
//
//private func getDocumentsDirectory() -> URL {
// return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
//}
//
//private func presentDocumentPicker() {
// guard let mixedAudioURL = recordingURL else { return }
// DispatchQueue.main.async {
// let documentPicker = UIDocumentPickerViewController(url: mixedAudioURL, in: .exportToService)
// documentPicker.delegate = self
// self.present(documentPicker, animated: true, completion: nil)
// }
//}
//
//private func saveRecordingToFile() {
// let fileManager = FileManager.default
// let documentsURL = getDocumentsDirectory().appendingPathComponent("savedRecordedAudio.m4a")
//
// do {
// if fileManager.fileExists(atPath: documentsURL.path) {
// try fileManager.removeItem(at: documentsURL)
// }
// try fileManager.moveItem(at: recordingURL, to: documentsURL)
// print("Recording saved to: \(documentsURL)")
// } catch {
// print("Error saving recording: \(error)")
// }
//}

View File

@@ -161,9 +161,10 @@ class KaraokeDetailsVC: UIViewController {
@IBAction func playNowBtnTapped(_ sender: LocalisedElementsButton) {
// let sb = UIStoryboard(name: K.StoryBoard.Karaoke, bundle: nil)
// let vcPush = sb.instantiateViewController(withIdentifier: "TestingKaraokeVC") as! TestingKaraokeVC
// let vcPush = sb.instantiateViewController(withIdentifier: "AVPlayerTesting") as! AVPlayerTesting
// self.present(vcPush, animated: true)
// return
var itemBuild = JwPlayerItemCreate(url: "")
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
@@ -181,16 +182,56 @@ class KaraokeDetailsVC: UIViewController {
DispatchQueue.main.async { [weak self] in
guard let self else{return}
Utilities.startProgressHUD()
FileManager.default.clearTmpDirectory()
let sb = UIStoryboard(name: K.StoryBoard.Karaoke, bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Karaoke.aVPlayerVC) as! AVPlayerVC
vc.videoURL = itemBuild.url
vc.titleVideo = itemBuild.titles
vc.modalPresentationStyle = .fullScreen
self.present(vc, animated: true)
let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Karaoke.jwKaraokePlayerVC) as! JWKaraokePlayerVC
do {
// Create a JWPlayerItem
let item = try JWPlayerItemBuilder()
.file(URL(string: itemBuild.url)!)
.posterImage(URL(string: itemBuild.poster ?? "")!)
.title(itemBuild.titles ?? "Karaoke")
.build()
// Create a JWPlayerConfiguration
let config = try JWPlayerConfigurationBuilder()
.playlist(items: [item])
.autostart(true)
.build()
vc.config = config
vc.videoTitle = itemBuild.titles
vc.videoUrl = itemBuild.url
vc.modalPresentationStyle = .overFullScreen
vc.modalTransitionStyle = .crossDissolve
// vc.documentAudioUrl = url
Utilities.dismissProgressHUD()
// Present the PlayerVC
self.present(vc, animated: true)
} catch {
print("Error creating JWPlayer configuration: \(error)")
Utilities.dismissProgressHUD()
}
// Dismiss the progress HUD after the view controller presentation
Utilities.dismissProgressHUD()
}
// DispatchQueue.main.async { [weak self] in
// guard let self else{return}
// Utilities.startProgressHUD()
// let sb = UIStoryboard(name: K.StoryBoard.Karaoke, bundle: nil)
// let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Karaoke.aVPlayerVC) as! AVPlayerVC
// vc.videoURL = itemBuild.url
// vc.titleVideo = itemBuild.titles
// vc.modalPresentationStyle = .fullScreen
// self.present(vc, animated: true)
// // Dismiss the progress HUD after the view controller presentation
// Utilities.dismissProgressHUD()
//
// }
}

View File

@@ -21,6 +21,14 @@
</array>
</customFonts>
<scenes>
<!--AV Player View Controller-->
<scene sceneID="Oht-rx-zQN">
<objects>
<avPlayerViewController storyboardIdentifier="AVPlayerTesting" videoGravity="AVLayerVideoGravityResizeAspect" id="NnH-Ku-2UG" customClass="AVPlayerTesting" customModule="WOKA" customModuleProvider="target" sceneMemberID="viewController"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="xvM-Nd-gV7" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-606" y="-27"/>
</scene>
<!--Karaoke ListingVC-->
<scene sceneID="s0d-6b-0kx">
<objects>
@@ -602,7 +610,7 @@
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" toolTip="Slide" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="VKq-Xn-4Nn">
<slider toolTip="Slide" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="VKq-Xn-4Nn">
<rect key="frame" x="54" y="0.0" width="296" height="31"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="minimumTrackTintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -825,7 +833,7 @@
</button>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="k45-7s-jnN" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="k45-7s-jnN" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="0.0" y="65" width="364" height="21"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="16"/>
@@ -892,78 +900,6 @@
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="lIa-J9-DOG">
<rect key="frame" x="20" y="606.5" width="374" height="97"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="hIr-xj-FN5">
<rect key="frame" x="0.0" y="0.0" width="374" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yv1-I1-YGZ" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="177" height="50"/>
<color key="backgroundColor" red="1" green="0.044904738164268321" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="N39-39-T3E"/>
</constraints>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="14"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="5" maxY="0.0"/>
<state key="normal" title="Start Recording" image="Microphone"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="playNowBtnTapped:" destination="fax-bi-Mb9" eventType="touchUpInside" id="Ruq-Xc-nQi"/>
<action selector="startRecordingBtnTapped:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="SOw-KK-zIp"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mHM-7B-XXx" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="197" y="0.0" width="177" height="50"/>
<color key="backgroundColor" name="TextDarkBlue"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="nIb-2q-pnZ"/>
</constraints>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="-10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="Play" image="PlayButtonSmall"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="playBtnTapped:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="tLm-vf-dht"/>
<action selector="playNowBtnTapped:" destination="fax-bi-Mb9" eventType="touchUpInside" id="VzV-ZD-BbA"/>
</connections>
</button>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3hw-ks-w1o" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="0.0" y="65" width="374" height="32"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" name="Exo2-Regular" family="Exo 2" pointSize="16"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="5" maxY="0.0"/>
<state key="normal" title="Download Recording">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="downloadRecording:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="dRc-xY-3VG"/>
<action selector="playNowBtnTapped:" destination="fax-bi-Mb9" eventType="touchUpInside" id="abN-kZ-2DQ"/>
</connections>
</button>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Nuf-TE-5LZ">
<rect key="frame" x="10" y="63" width="45" height="45"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -978,23 +914,118 @@
<action selector="backBtnTapped:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="oPW-n3-xjb"/>
</connections>
</button>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="yek-VM-Cus">
<rect key="frame" x="20" y="612" width="374" height="86"/>
<subviews>
<stackView hidden="YES" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="Oj2-hr-beY">
<rect key="frame" x="0.0" y="0.0" width="374" height="10"/>
<subviews>
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="Vsm-wu-cKE">
<rect key="frame" x="0.0" y="0.0" width="374" height="0.0"/>
<color key="color" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</activityIndicatorView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Loading Karaoke..." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4h3-oT-6Fg">
<rect key="frame" x="0.0" y="10" width="374" height="0.0"/>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="15"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="7RJ-zB-bI1">
<rect key="frame" x="0.0" y="0.0" width="374" height="86"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="fCQ-xT-zM8">
<rect key="frame" x="0.0" y="0.0" width="374" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vbj-gW-VZl" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="177" height="50"/>
<color key="backgroundColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="ASM-xe-c9a"/>
</constraints>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="14"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="5" maxY="0.0"/>
<state key="normal" title="Start Recording" image="Microphone"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="playNowBtnTapped:" destination="fax-bi-Mb9" eventType="touchUpInside" id="ru7-Wv-EJr"/>
<action selector="startRecordingBtnTapped:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="2bh-Cr-Joy"/>
<action selector="startStopRecording:" destination="kQu-aO-Siv" eventType="touchUpInside" id="7pG-pk-Hk5"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4rT-nK-Wb6" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="197" y="0.0" width="177" height="50"/>
<color key="backgroundColor" name="TextDarkBlue"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="zTv-rH-ydT"/>
</constraints>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="-10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="Play" image="PlayButtonSmall"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="playBtnTapped:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="WZm-M9-WLE"/>
<action selector="playNowBtnTapped:" destination="fax-bi-Mb9" eventType="touchUpInside" id="NX9-0v-D3v"/>
<action selector="playPauseBtn:" destination="kQu-aO-Siv" eventType="touchUpInside" id="bpF-JM-8Dq"/>
</connections>
</button>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Ui-AF-Hlc" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="0.0" y="65" width="374" height="21"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="16"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="5" maxY="0.0"/>
<state key="normal" title="Download Recording" image="icloud.and.arrow.down.fill" catalog="system"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="downloadRecording:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="kED-rq-2EY"/>
<action selector="playNowBtnTapped:" destination="fax-bi-Mb9" eventType="touchUpInside" id="Smw-Oi-Xnt"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="fhs-yV-fEZ"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="lIa-J9-DOG" firstAttribute="centerY" secondItem="fhs-yV-fEZ" secondAttribute="centerY" constant="200" id="2hX-z2-lum"/>
<constraint firstAttribute="trailing" secondItem="lIa-J9-DOG" secondAttribute="trailing" constant="20" id="7WR-NN-0zd"/>
<constraint firstItem="yek-VM-Cus" firstAttribute="centerY" secondItem="fhs-yV-fEZ" secondAttribute="centerY" constant="200" id="0CQ-IK-CSM"/>
<constraint firstItem="yek-VM-Cus" firstAttribute="leading" secondItem="fhs-yV-fEZ" secondAttribute="leading" constant="20" id="0qJ-R4-ZTb"/>
<constraint firstItem="Nuf-TE-5LZ" firstAttribute="top" secondItem="fhs-yV-fEZ" secondAttribute="top" constant="15" id="7jB-UT-Xqq"/>
<constraint firstItem="fhs-yV-fEZ" firstAttribute="trailing" secondItem="yek-VM-Cus" secondAttribute="trailing" constant="20" id="Omt-Ig-58p"/>
<constraint firstItem="Nuf-TE-5LZ" firstAttribute="leading" secondItem="fhs-yV-fEZ" secondAttribute="leading" constant="10" id="Tcl-yf-D2V"/>
<constraint firstItem="lIa-J9-DOG" firstAttribute="leading" secondItem="fhs-yV-fEZ" secondAttribute="leading" constant="20" id="yH2-iw-QCt"/>
</constraints>
</view>
<connections>
<outlet property="backButton" destination="Nuf-TE-5LZ" id="syG-po-xEv"/>
<outlet property="downloadRecordingBtn" destination="3hw-ks-w1o" id="bWR-kY-K1G"/>
<outlet property="outerStack" destination="lIa-J9-DOG" id="uBJ-C7-rCI"/>
<outlet property="playBtn" destination="mHM-7B-XXx" id="qso-dg-U5b"/>
<outlet property="startRecordBtn" destination="yv1-I1-YGZ" id="Xf6-hb-4Qd"/>
<outlet property="downloadRecordingBtn" destination="3Ui-AF-Hlc" id="9TA-QY-4xw"/>
<outlet property="karaokeLoading" destination="Vsm-wu-cKE" id="GBV-UM-lT7"/>
<outlet property="karaokeStack" destination="Oj2-hr-beY" id="apD-yP-Yfh"/>
<outlet property="outerStack" destination="yek-VM-Cus" id="nRc-sO-HjJ"/>
<outlet property="playBtn" destination="4rT-nK-Wb6" id="XLE-Da-4YA"/>
<outlet property="startRecordBtn" destination="vbj-gW-VZl" id="QV4-c3-Fub"/>
<outlet property="startStopRecordingStack" destination="7RJ-zB-bI1" id="LeT-d7-eoh"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="s0j-fC-RFe" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>