I am working on iOS Webrtc and want to make Audio only call with Audio Only SDP
I am creating Offer as bellow but SDP still has audio and video in it
What is the correct way to create AUDIO only offer
NSDictionary *mandatoryConstraints = #{
#"OfferToReceiveAudio" : #"true",
#"OfferToReceiveVideo" : #"false"
};
RTCMediaConstraints* constraints =
[[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatoryConstraints
optionalConstraints:nil];
I was able to do this.
Create your peerConnection with those constraints
Create an AudioTrack
Create a MediaStream, add the audio track to the MediaStream
Add the MediaStream to your peerConnection
Create the offer and send to the receiver
On the receiving side, you do the reverse
I am able to find the solution by creating Video Sender only if video is enabled as below.
if (_videoAllowed) {
[self createVideoSender];
}
Related
I'm creating custom video player, and i want to create toggle button for CC.
I saw this post : IOS AVPlayer cannot disable closed captions
So I tried :
AVMediaSelectionGroup *group = [self.avPlayer.currentItem.asset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicLegible];
[self.avPlayer.currentItem selectMediaOption:nil inMediaSelectionGroup:group];
Didn't work.. cc still visible.
also tried :
AVPlayerItemLegibleOutput *output = [[AVPlayerItemLegibleOutput alloc] init];
[output setDelegate:self queue:dispatch_get_main_queue()];
[output setSuppressesPlayerRendering:true];
[self.avPlayer.currentItem addOutput:output];
It's hide the the cc, but how can I unhide them? ,I tried:
[output setSuppressesPlayerRendering:true];
but the cc freeze on the screen.
thanks!
Objective C: This one works for me. Even I wanted to do the same thing.
To off subtitles
AVMediaSelectionGroup *subtitleSelectionGroup = [_playerItem.asset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicLegible];
[_playerItem selectMediaOption:NULL inMediaSelectionGroup:subtitleSelectionGroup];
To show it again I do this:
AVMediaSelectionOption* option = [subtitleSelectionGroup.options objectAtIndex:subtitleIndex-1]; // I did -1 because OFF was 0 for my case
[_playerItem selectMediaOption:option inMediaSelectionGroup:subtitleSelectionGroup];
This is the code I am using to play a sound with AVAudioPlayerNode. It is just playing the last sound of the beats array. On iPhone, all sounds from the beats array are playing simultaneously with the same function.
-(void)playMix{
for (int i = 0; i< mix.beatsArray.count;i++) {
beat = [[WatchBeatObject alloc] initWithFileName:mix.beatsArray[i].fileName];
[beat.audioPlayerNode play];
[beat.audioPlayerNode scheduleBuffer:beat.buffer atTime:nil options:AVAudioPlayerNodeBufferLoops completionHandler:^{
}];
}
}
N.B: Method initWithFileName: handles initializing and creating AVAudioPlayerNode and everything needed.
Thank you in advance.
Does that WatchBeatObject has any category option in AVAudioSession to set AVAudioSessionCategoryAmbient? If yes, set it, they would mix different sound.
I have implemented MobileVLCKit in iOS by using MobileVLCKit framework. I have an issue,
When I declare the player #Interface the streaming and voice is working well.
#import <MobileVLCKit/MobileVLCKit.h>
#interface ViewController ()<VLCMediaPlayerDelegate>{
VLCMediaPlayer *vlcPlayer1
}
#end
But, declare the VLCMediaPlayer object at local function the video preview not displayed but, audio id playing.
- (void)viewDidLoad {
[super viewDidLoad];
VLCMediaPlayer *vlcPlayer1 = [[VLCMediaPlayer alloc] initWithOptions:nil];
vlcPlayer1.drawable = view;
media = [VLCMedia mediaWithURL:[NSURL URLWithString: UrlString]];
[vlcPlayer1 setMedia:media];
[vlcPlayer1 play];
}
How can I resolve the issue. Because, I need to create the view dynamically.
Try this:
[vlcplayer.media addOptions:#{ #"network-caching" : #300}];
If it doesn't work, replace 300 with a bigger value.
That may work.
So both of these questions/answers put me on the right path, but this is ultimately what worked for me.
NSURL* _uri = [NSURL URLWithString:uri];
NSArray* initOptions = [NSArray arrayWithObjects:#"--codec=avcodec", "--network-caching=10000", nil];
self.player = [[VLCMediaPlayer alloc] initWithOptions:initOptions];
self.player.media = [VLCMedia mediaWithURL:_uri];
It looks like the "addOptions" is valid, but my particular use case wasn't picking it up, and instead I had to actually initialize the VLCMediaPlayer with the options from the get go. Worked out nice because it actually fits much better with other JAVA/Android/CMD line VLC api's.
I'm trying to get a .pls stream from a shoutcast server to play in my ios app. So far i've been unsuccessful. I've red a lot of posts on stackoverflow but non of these were of any help.
Can anyone please explain to me, if its even possible, how to get .pls to stream?
all you need is to list the port of you radio, here is one working example:
in - (void)viewDidLoad
NSURL *vibes = [NSURL URLWithString:#"http://website.com:8002"];
vPlayer = [[AVPlayer alloc] initWithURL:vibes];
self.myViewVolume = [[MPVolumeView alloc] initWithFrame:CGRectMake(20, 330, 280, 50)];
[self.myViewVolume sizeToFit];
[self.view addSubview:self.myViewVolume];
you need to create an instance of AVPlayer in your .m file , here it is vPlayer
do not forget to add AVFoundation framework to you project, you can play and stop the stream with [player play] and [player stop]
One problem with AVPlayer is the lack of easy volume control, you can add one with mpViewVolume.
I am also working on radio app and by far AVPlayer is the best to play shoutcast streams.
#Walid Hussain
it worked for me using AVPlayer
link with AVFoundation.framework
//import needed
#import <AVFoundation/AVFoundation.h>
// declaration for the player
AVPlayer * radioPlayer;
// play
NSURL * url = [NSURL URLWithString:#"http://energy10.egihosting.com:9636"];
radioPlayer = [[AVPlayer playerWithURL:url] retain];
[radioPlayer play];
As you know,play a movie with MPMoviePlayerController object using
[[MPMoviePlayerController alloc] initWithContentURL: aURL];
now ,i want to achieve a custom NSURLProtocol in which i will decrypt a movie source that had be encrypt by AlgorithmDES.
Is that possibility? thanks for giving any ideas.need you help~
UPDATE: I spoke to Apple about this and it's not possible to use MPMoviePlayerController with a NSURLProtocol subclass at the moment!
Hej,
I am not sure but it could be possible. I am currently working on something similar but haven't got it fully working. What I have found out is that MPMoviePlayerController interacts with my custom NSURLProtocol subclass BUT it seems to be important to take the HTTPHeaders of the NSURLRequest into account because they define a range of bytes the MPMoviePlayerController needs.
If you dump them in your NSURLProtocol subclass you will get something like this twice for the start:
2011-01-16 17:00:47.287 iPhoneApp[1177:5f03] Start loading from request: {
Range = "bytes=0-1";
}
So my GUESS is that as long as you can provide the correct range and return a mp4 file that can be played by the MPMoviePlayerController it should be possible!
EDIT: Here is a interesting link: Protecting resources in iPhone and iPad apps
The solution is to proxy requests through a local HTTP server. I have accomplished this using CocoaHTTPServer.
Look at the HTTPAsyncFileResponse example.
There is one more solution as of iOS 7. You can use a AVAssetResourceLoaderDelegate for AVAssetResourceLoader. But this will only work with AVPlayer then.
There is a demo project by apple called AVARLDelegateDemo have a look at it and you should find what you need. (I think linking to it isn't a good idea, so just search for it in the Developer Library on developer.apple.com) Then use any custom URL scheme (without declaring a NSURLProtocol) and handle that URL scheme in the AVAssetResourceLoaderDelegate.
If there is a huge interest I could provide a proof of concept gist.
#property AVPlayerViewController *avPlayerVC;
#property NSData *yourDataSource
// initialise avPlayerVC
NSURL *dummyURL = [NSURL URLWithString:#"foobar://dummy.mov"];// a non-reachable URL will force the use of the resourceLoader
AVURLAsset *asset = [AVURLAsset assetWithURL:dummyURL];
[asset.resourceLoader setDelegate:self queue:dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)];
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
self.avPlayerVC.player = [AVPlayer playerWithPlayerItem:item];
self.avPlayerVC.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
// implement AVAssetResourceLoaderDelegate
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {
loadingRequest.contentInformationRequest.contentType = (__bridge NSString *)kUTTypeQuickTimeMovie;
loadingRequest.contentInformationRequest.contentLength = self.yourDataSource.length;
loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
NSRange range = NSMakeRange((NSUInteger)loadingRequest.dataRequest.requestedOffset, loadingRequest.dataRequest.requestedLength);
[loadingRequest.dataRequest respondWithData:[self.yourDataSource subdataWithRange:range]];
[loadingRequest finishLoading];
return YES;
}
Notice the use of a dummy URL to force AVPlayer to use the AVAssetResourceLoaderDelegate methods instead of accessing the URL directly.