Cast Sender App Shows Pause Button Instead of Stop Button - ios

So I am trying to build a sender app for chromecast that will stream Live feeds only. The trouble is the various framework dialogs all show a Pause button, when in fact I need a Stop button (or for the feed to at least jump back to current live time when it is resumed)
The only information I can find on this through the documentation is some vague snippet
When your sender app is playing a video or audio live stream, the SDK automatically displays a play/stop button in place of the play/pause button in the mini controller.
When I create the GCKMediaInformation object to load on the chromecast, I set its Media Stream Type to Live with a content type of "vnd.apple.mpegURL" But this has no effect.
Does anybody have any idea how I can make the stop button appear instead of the pause button?
EDIT:
A strip down version of the logic used to load live stream feed
let metaData = GCKMediaMetadata(metadataType: .generic)
metaData.setString(selectedChannel!.channelName, forKey: kGCKMetadataKeyTitle)
metaData.addImage(GCKImage(url: URL(string: selectedChannel!.imgURL)!, width: 10, height: 20))
mediaInfo = GCKMediaInformation(contentID: selectedChannel!.vidURL, streamType: GCKMediaStreamType.live, contentType: "vnd.apple.mpegURL", metadata: metaData, streamDuration: 0, mediaTracks: nil, textTrackStyle: nil, customData: nil)
if sessionManager.currentCastSession != nil {
switchToCastingMode()
}
func switchToCastingMode() {
print("switching to CAST mode")
if let session = GCKCastContext.sharedInstance().sessionManager.currentCastSession {
if session.remoteMediaClient?.mediaStatus?.mediaInformation?.contentID != mediaInfo?.contentID {
session.remoteMediaClient?.loadMedia(mediaInfo!, autoplay: true)
GCKCastContext.sharedInstance().presentDefaultExpandedMediaControls()
}
}
}
I have also tried changing the media stream type to other values, but this has no effect either :(

Related

iOS How to trigger video to keep playing after exiting fullscreen?

I'm building a website that plays video in iOS. I have a fullscreen button working in iOS however the video pauses when exiting fullscreen. Does anyone know a way to either force the video to continue to play upon exiting fullscreen or how to set up a listener that triggers the video to autoplay upon exiting fullscreen?
here is my code:
<script>
var video = document.getElementById('tv'),
play = document.getElementById('fullscreenbutton'),
time;
video.addEventListener('webkitbeginfullscreen', function() {
play.innerText = '';
window.clearInterval(time);
});
video.addEventListener('webkitendfullscreen', function() {
tv.autoplay();
});
play.addEventListener('touchstart', function() {
time = window.setInterval(function() {
try {
video.webkitEnterFullscreen();
}
catch(e) {}
}, 250);
play.innerText = 'loading ...';
tv.play();
});
</script>
'''
You can use WKScriptMessageHandler in your iOS app when a button to exit fullscreen mode is tapped then resume your video player.
Here is a workaround on how I would handle this situation.
Native iOS + JavaScript
1 Step: Website front end part
When exit full screen button is tapped on your website emit an event give it a unique name something like "exitFullScreenEvent"
2 Step: iOS App
import WebKit
ViewController: WKScriptMessageHandler {
// Helper method to set configurations for your webView in iOS
func configureWebView() {
///Add the script message handler into the content controller.
let contentController = WKUserContentController()
/// Give it the same name as on the web front-end part
contentController.add(self, name: "exitFullScreenEvent")
let config = WKWebViewConfiguration()
config.userContentController = contentController
/// Most important, when initilizing your web view pass the configuration above
let webView = WKWebView(frame: .zero, configuration: config)
// Layout/add constraints to your webView
// .....
}
// Delegate method to listen an event emitted from your website
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
// TODO: - Resume/ Play your video
}
}
Pure Website (Javascript only)
For website only which runs in pure Javascript without any iOS related components and on Safari browser you might want to check this webkitjs displayingfullscreen
I Haven't used it before but it worth reading the doc.
But another work around without putting lots of effort is to compare your video player's screen size with the browsers window size ie.. check if browser is full screen if so get the full screen width if it's the same with your video player's size then video is in full screen.

How can I detect if my audio streaming url can not be play by iOS device - swift3

I am making an iOS Radio app with Swift 3! Now it is working and playing all the url address audio streaming well. But when I am in my workplace the Wifi has restrictions for Play audios streaming, so the app just works with Mobile Data.
When I click on Play button it change to Pause and does not send any sounds, It does not play and the console does not show any connectivity error or something like that. I want to know when the firewall or proxy of some WIFI network is blocking my app to send some UIAlert and change the Pause icon to Play ( if i do not do it the user will be waiting for the music).
I am using Swift 3.0 Xcode 8 , AVPlayer to play the audio. I have tried .addPeriodicTimerObserver, I have validated the url and did a lot of things but I could not get the result that I am looking for. Can some one help me?
var urlStreaming:String = "http://someurl"
playerStreaming = AVPlayer(url: URL(string: url)!)
playerLayer = AVPlayerLayer(player: playerStreaming)
playerLayer.frame = CGRect(x:0, y: 0, width:1, height: 10)
self.view.layer.addsublayer(playerLayer)
playerStreaming?.play()
My playerStreaming?.play() is not sending me nothing when It can not play because it starts trying to play but after some seconds it stops and it does not send anything. When I using WIFI connection of my workplace it happens, but If i change it to mobile data I can listening the audio. If i play from another wifi connection for example my house, park or starbuck coffee wifi I can listening it too without problems.
I know that the Wifi connection in my workplace has restriction (blocked by firewall or proxy actually I am not sure. )for audio streaming.
I have been looking for a lot of options and I tried all of them but i had gotten the result that I am looking for.
Can you help me?
I think i found something to check it. What do you thing #zombie?
I checked if the url is valid or how much it takes to play.
P.S. Maybe I will change the Time Out value , now it is taking to much time.
Console shows:
Error Info: -> Error Domain=NSURLErrorDomain Code= -1001 "the request time out" . i think I can validate if my error is null or not. if it is null I can show a UIAlert
let urltest = URL(string: yourul)
let task = URlSession.shared.dataTask(with: urlTest!){
data, response, error in
if(error != nil){
print("Error info: -> \(error!)")
//I think here I can changes the Image if i found a error
}
else{
print("It is going to be play without problem")
}
}
You can listen for error by
NotificationCenter.default.addObserver(self, selector: #selector(playerItemFailedToPlay(_:)), name: NSNotification.Name.AVPlayerItemFailedToPlayToEndTime, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(playerItemFailedToPlay(_:)), name: NSNotification.Name.AVPlayerItemPlaybackStalled, object: nil)
func playerItemFailedToPlay(_ notification: Notification) {
let error = notification.userInfo?.first(where: { $0.value is Error }) as? Error
}
don't for get to remove the observer
deinit {
NotificationCenter.default.removeObserver(self)
}

Audio playback lock screen controls not displaying on iPhone

I am testing this using iOS 10.2 on my actual iPhone 6s device.
I am playing streamed audio and am able to play/pause audio, skip tracks, etc. I also have enabled background modes and the audio plays in the background and continues through a playlist properly. The only issue I am having is getting the lock screen controls to show up. Nothing displays at all...
In viewDidLoad() of my MainViewController, right when my app launches, I call this...
func setupAudioSession(){
UIApplication.shared.beginReceivingRemoteControlEvents()
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.mixWithOthers)
self.becomeFirstResponder()
do {
try AVAudioSession.sharedInstance().setActive(true)
print("AVAudioSession is Active")
} catch let error as NSError {
print(error.localizedDescription)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
and then in my AudioPlayer class after I begin playing audio I call ...
func setupLockScreen(){
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.nextTrackCommand.isEnabled = true
commandCenter.nextTrackCommand.addTarget(self, action:#selector(skipTrack))
MPNowPlayingInfoCenter.default().nowPlayingInfo = [MPMediaItemPropertyTitle: "TESTING"]
}
When I lock my iPhone and then tap the power button again to go to the lock screen, the audio controls are not displayed at all. It is as if no audio is playing, I just see my normal background photo. Also no controls are displayed in the control panel (swiping up on home screen and then swiping left to where the music controls should be).
Is the issue because I am not using AVAudioPlayer or AVPlayer? But then how does, for example, Spotify get the lock screen controls to display using their own custom audio player? Thanks for any advice / help
The issue turned out to be this line...
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.duckOthers)
Once I changed it to
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: [])
everything worked fine. So it seems that passing in any argument for AVAudioSessionCategoryPlaybackOptions causes the lock screen controls to not display. I also tried passing in .mixWithOthers an that too caused the lock screen controls to not be displayed
In Swift 4. This example is only to show the player on the lock screen and works with iOS 11. To know how to play auidio on the device you can follow this thread https://stackoverflow.com/a/47710809/1283517
import MediaPlayer
import AVFoundation
Declare player
var player : AVPlayer?
Now create a function
func setupLockScreen(){
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.nextTrackCommand.isEnabled = true
commandCenter.togglePlayPauseCommand.addTarget(self, action: #selector(controlPause))
MPNowPlayingInfoCenter.default().nowPlayingInfo = [MPMediaItemPropertyTitle: currentStation]
}
now create a function for control play and pause event. I have created a BOOL "isPlaying" to determine the status of the player.
#objc func controlPause() {
if isPlaying == true {
player?.pause()
isPlaying = false
} else {
player?.play()
isPlaying = true
}
}
And ready. Now the player will be displayed on the lock screen
Yes, for the lock screen to work you need to use iOS APIs to play audio. Not sure how Spotify does it but they may be using a second audio session in parallel for this purpose and use the controls to control both. Your background handler (the singleton in my case) could start playing the second audio with 0 volume when it goes into background and stop it when in foreground. I haven't tested it myself but an option to try.

ReplayKit sharing video to facebook has no commentary

I'm recording a video with commentary, and I'm using replaykit. Everything is working fine on iPhone, but when I share to facebook, my videos has no sound at all. I've downloaded a video to my mac and it's m4v with sound. But when I'm trying to share it from my mac to facebook it doesn't has sound too. On youtube it works very good. Not sure is there any way I can fix it? Can I record a screen and commentary without replaykit and pass app review?
Start:
RPScreenRecorder.shared().isMicrophoneEnabled = true
RPScreenRecorder.shared().startRecording { (error) in
if error == nil {
//TODO: show RECORDING view
print("start recording")
}
}
Stop:
RPScreenRecorder.shared().stopRecording { (previewViewController, error) in
if let previewVC = previewViewController, error == nil {
previewVC.previewControllerDelegate = self
self.present(previewVC, animated: true, completion: nil)
}
}
Seems to be Fixed by Apple
(on the latest IOS 11 Beta's update)
Ofir Malachi I will write it as an answer, I used some parts of Spitfire library, I'm doing a screenshot of this part of the screen I want to "record" every 0.1 second. I'm merging those images to a video. In the same time I'm recording audio. At the end I've got "output.mov" and "recording.m4a". I'm using AVAssetExportSession to merge it asynchronously to the mp4 file.

Using Spotify/background music with camera open

I have an app that needs to have:
Background music playing while using the app (eg. spotify)
Background music playing while watching movie from AVPlayer
Stop the music when recording a video
Like Snapchat, the camera-viewcontroller is part of a "swipeview" and therefore always on.
However, when opening and closing the app, the music makes a short "crack" noise/sound that ruins the music.
I recorded it here:
https://soundcloud.com/morten-stulen/hacky-sound-ios
(3 occurrences)
I use these settings for changing the AVAudiosession in the appdelegate didFinishLaunchingWithOptions:
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord,withOptions:
[AVAudioSessionCategoryOptions.MixWithOthers,
AVAudioSessionCategoryOptions.DefaultToSpeaker])
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("error")
}
I use the LLSimpleCamera control for video recording and I've set the session there to:
_session.automaticallyConfiguresApplicationAudioSession = NO;
It seems others have the same problem with other camera libraries as well:
https://github.com/rFlex/SCRecorder/issues/127
https://github.com/rFlex/SCRecorder/issues/224
This guy removed the audioDeviceInput, but I kinda need that for recording video.
https://github.com/omergul123/LLSimpleCamera/issues/48
I also tried with Apple's code "AvCam", and I still have the same issue. How does Snapchat do this?!
Any help would be greatly appreciated, and I'll gladly provide more info or code!
I do something similar to what you're wanting, but without the camera aspect, but I think this will do what you want. My app allows background audio that will mix with non-fullscreen video/audio. When the user plays an audio file or a full screen video file, I stop the background audio completely.
The reason I do SoloAmbient then Playback is because I allow my audio to be played in the background when the device is locked. Going SoloAmbient will stop all background music playing and then switching to Playback lets my audio play in the app as well as in the background.
This is why you see a call to a method that sets the lock screen information in the Unload method. In this case, it is nulling it out so that there is no lock screen info.
In AppDelegate.swift
//MARK: Audio Session Mixing
func allowBackgroundAudio()
{
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: .MixWithOthers)
} catch {
NSLog("AVAudioSession SetCategory - Playback:MixWithOthers failed")
}
}
func preventBackgroundAudio()
{
do {
//Ask for Solo Ambient to prevent any background audio playing, then change to normal Playback so we can play while locked
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategorySoloAmbient)
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
NSLog("AVAudioSession SetCategory - SoloAmbient failed")
}
}
When I want to stop background audio, for example when playing an audio track that should be alone, I do the following:
In MyAudioPlayer.swift
func playUrl(url: NSURL?, backgroundImageUrl: NSURL?, title: String, subtitle: String)
{
ForgeHelper.appDelegate().preventBackgroundAudio()
if _mediaPlayer == nil {
self._mediaPlayer = MediaPlayer()
_mediaPlayer!.delegate = self
}
//... Code removed for brevity
}
And when I'm done with my media playing, I do this:
private func unloadMediaPlayer()
{
if _mediaPlayer != nil {
_mediaPlayer!.unload()
self._mediaPlayer = nil
}
_controlView.updateForProgress(0, duration: 0, animate: false)
ForgeHelper.appDelegate().allowBackgroundAudio()
setLockScreenInfo()
}
Hope this helps you out!

Resources