I have a remote mp3 (small file, just a few seconds) which I have the URL.
I need to play it on an App that uses iOS 4.
The URL is not exactly a .mp3 file, but it is a dynamic .php url that requests the .mp3 file. If I put that php route in the browser it downloads the mp3 file.
I am trying to use this project (https://github.com/mattgallagher/AudioStreamer) but it isn't working. The audio starts but it only plays a part of it.
How can I do it?
If it's truly just a small (and static, non-streaming) mp3 file, why not consider doing something like:
NSError * error = nil;
AVAudioPlayer * avPlayerObject =
[[AVAudioPlayer alloc] initWithContentsOfURL: yourRemoteURL error:&error];
if(avPlayerObject)
{
[avPlayerObject play];
}
Check out Apple's AVAudioPlayer class (documentation linked for you).
Related
I have edited my videos in final cut pro and used their export to http live streaming, which includes an audio, cell low and hi video, wifi low and hi, .m3u8 and index files. I have put all the files onto my web server and am using this to call the videos
-(IBAction)introVideo:(id)sender
{
NSLog(#"intro button pressed");
NSString *url = #"http://www.andalee.com/iPhoneVideos/intro/Intro.m3u8";
MPMoviePlayerViewController* moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:url]];
[self presentMoviePlayerViewControllerAnimated:moviePlayer];
}
(Side note: how should this be released?)
Here is the Index.m3u8
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=225416,CODECS="mp4a.40.2, avc1.42e015"
Intro%20-%20Cellular%20Low.segments/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=480386,CODECS="mp4a.40.2, avc1.42e015"
Intro%20-%20Cellular%20High.segments/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=751434,CODECS="mp4a.40.2, avc1.42e01e"
Intro%20-%20Wi-Fi%20Low.segments/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1250210,CODECS="mp4a.40.2, avc1.4d401e"
Intro%20-%20Wi-Fi%20High.segments/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2545049,CODECS="mp4a.40.2, avc1.4d401e"
Intro%20-%20Broadband%20Low.segments/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=5056100,CODECS="mp4a.40.2, avc1.4d401f"
Intro%20-%20Broadband%20High.segments/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=33290,CODECS="mp4a.40.2"
Intro%20-%20Audio%20for%20HTTP%20Live%20Streaming.segments/prog_index.m3u8
When I test my app I initially get video and sound, but after 30 seconds I lose video while the audio continues to play. Any ideas what would be causing this?
This could simply be caused by a low bandwidth condition, which will trigger a bitrate change (in this case to the audio only version). If you try it in the emulator with a local server it might work correctly.
Most likely the file which is used next after the intro has wrong codec or the path is not right. Make sure all of the paths in Intro.m3u8 are correct and reachable from outside.
I have problem when trying to play some mp3 files on iOS app.
First, I noticed that these files was also not working on Safari for iOS, but now I am having files that works on Safari for iOS, and doesn't work on my App.
I am using thi code to play mp3 audio files:
NSString *pronociationPath = …..
if (pronociationPath != nil)
{
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:pronociationPath];
NSError *error;
self.player=[[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error] autorelease];
[fileURL release];
[self.player setNumberOfLoops:0];
if (self.player == nil) {
NSLog(#"%#",error);
}
else
{
[self.player prepareToPlay];
[self.player play];
}
}
And I am having this error for a file that works on Safari iOS:
Error Domain=NSOSStatusErrorDomain Code=1685348671 "The operation
couldn’t be completed. (OSStatus error 1685348671.)"
Is something wrong with my code?
Is there any guide to create safe mp3 files for iOS Apps ?
I've seen Apple documentation, but I don't see any useful informations https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/MultimediaPG/UsingAudio/UsingAudio.html#//apple_ref/doc/uid/TP40009767-CH2-SW28
I also received same error (OSStatus error 1685348671) when I tried to play mp3 files on iOS 4.3.
Later on I found that it was the mp3 sound problem which made it incompatible to be played in iOS 4.3. So, I used iTunes Player to convert new version of mp3 sound with existing one. Now it works fine and better.
Steps:
Open your current mp3 sound in iTunes
Select it and Click on "Advanced" Menu >> "Create MP3 Version"
It wil create copy of current audio. Use newly created mp3 file for your app.
It helped me. I hope it might help others as well. All the best!
In order to load a sound file, I have the following code in my application :
- (id) init:(NSString*)a_filename ext:(NSString*)a_ext
{
...
NSString *t_soundFilePath = [CFileLoader getPathForResource:filename WithExtension:ext];
NSURL *t_fileURL = [[[NSURL alloc] initFileURLWithPath: t_soundFilePath] autorelease];
player = [[AVAudioPlayer alloc] initWithContentsOfURL: t_fileURL error: nil];
[player prepareToPlay];
...
}
All the sounds that I load are in my bundle, so I would like to know if the method "initwithcontentsofurl" stream the sound file or if all the file is cached.
I have a lot of sprites in my app so I want to minimize memory space used for sounds.
thx for your help
I used AVPlayer (not AVAudioPlayer) to stream background audio.
Sounds that are played using the AVAudioPlayer are streamed real time from storage. The drawback being that you can occasionally notice a small lag when it is due to start up. If you use OpenAL the sounds are loaded entirely into memory.
There's a good discussion of this sort of thing in the ObjectAL documentation - a library that is meant to simplify the playing of sounds and effects on the iPhone.
If you want to stream audio in your app you can use the following player instead of using AVAudioPlayer
https://github.com/mattgallagher/AudioStreamer
For this player you don't need to put sound files in your bundle, you can put them at server and use url to stream audio.
Hope, this wil help you.
" The AVAudioPlayer class does not provide support for streaming audio
based on HTTP URL's. The URL used with initWithContentsOfURL: must be
a File URL (file://). That is, a local path".
https://developer.apple.com/library/ios/qa/qa1634/_index.html
But you can work around - for example write asynchronously to local file, and init AVAudioPlayer with this file URL, it will work.
Playing Youtube video in the app is easy and well documented around.
There are two problems with that:
after closing Youtube player, if user wants to play it again it has to wait for online streaming again
can't play offline (load video at home to watch on the road)
Does anyone have code to:
download Youtube video to documents folder and show progress of download
play downloaded video by loading file from documents folder (meaning even when not connected to the internet)
To download the video from YouTube:
Get the URL to download from, via the YouTube API or whatever other method.
Create an NSOutputStream or NSFileHandle opened on a temporary file (in NSTemporaryDirectory() or a temp-named file in your Documents directory).
Set up your progress bar and whatever else you need to do.
Allocate and start an NSURLConnection to fetch the file from the URL. Do not use sendSynchronousRequest:returningResponse:error:, of course.
In the connection:didReceiveResponse: delegate method, read out the length of data to be downloaded for proper updating of the progress bar.
In the connection:didReceiveData: delegate method, write the data to the output stream/file handle and update the progress bar as necessary.
In connectionDidFinishLoading: or connection:didFailWithError:, close the output stream/file handle and rename or delete the temporary file as appropriate.
To play it back, just use NSURL's fileURLWithPath: to create a URL pointing to the local file in the Documents directory and play it as you would any remote video.
Ive used classes from this project: https://github.com/larcus94/LBYouTubeView
It works fine for me.
I can download youtube videos.
I used this code:
LBYouTubeExtractor *extractor = [[[LBYouTubeExtractor alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:(#"http://www.youtube.com/watch?v=%#"), self.videoID ]] quality:LBYouTubeVideoQualityLarge] autorelease];
[extractor extractVideoURLWithCompletionBlock:^(NSURL *videoURL, NSError *error) {
if(!error) {
NSLog(#"Did extract video URL using completion block: %#", videoURL);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL: videoURL];
NSString *pathToDocs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = [NSString stringWithFormat:(#"video_%#.mp4"), self.videoID ];
[data writeToFile:[pathTODocs stringByAppendingPathComponent:filename] atomically:YES];
NSLog(#"File %# successfully saved", filename);
});
} else {
NSLog(#"Failed extracting video URL using block due to error:%#", error);
}
}];
You can show progress of downloading using technique described in the posts above.
Here is my example: https://github.com/comonitos/youtube_video
I used PSYouTubeExtractor.h class by Peter Steinberger It can get youtube mp4 video url and than downloading and viewing is not a problem
NSURLConnection
+
NSNotificationCenter
+
PSYouTubeExtractor
+
NSMutableData
check these projects -
https://github.com/iosdeveloper/MyTube
https://github.com/pvinis/mytube
these will definitely help you!!
I don't personally know how to download youtube videos (and the code is too big to put in an answer here).
However, here's a complete youtube downloading example here.
It's an open source youtube downloader called LoadTube: here's the a link to the source code.
I would play the video and figure out where the temp file is being stored. If you can get access to it, copy it into some document folder for offline viewing.
I'm using the following to play an m4a file:
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: fileName];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
AudioServicesPlaySystemSound(soundID);
It works fine on the simulator but I hear nothing on the device. Sounds files I'm using all stay in the bundle. Here is what filePath looks like from the device:
file://localhost/var/mobile/Applications/418945F3-3711-4B4D-BC65-0D78993C77FB/African%20Adventure.app/Switch%201.m4a
Is there an issue with the file path or any thing different I need to do for the device?
Just as a sidenote - I was having the exact same problem and spent probably close to an hour on converting files to the correct format, etc.. Yet the problem was the "mute" switch on the iPad. So even though the volume was up, and I could hear other sounds on the iPad, because the mute switch was turned on, it wasn't playing system sounds.
To add to the confusion, this app uses text-to-speech and the volume coming from the dictation was perfectly fine, it was only the sounds coming from AudioServicesPlaySystemSound() that weren't being played.
I had trouble with this too. Finally I realised it was because AudioServices can only play audio with the following constratints.
Sound files that you play using this
function must be:
- No longer than 30 seconds in duration
- In linear PCM or IMA4 (IMA/ADPCM) format
- Packaged in a .caf, .aif, or .wav file
From Apple docs: http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/SystemSoundServicesReference/Reference/reference.html
You might want to use the AVAudioPlayer instead of AudioServices.
The following code will take an audio file (.m4a) and play the audio file 1 time. Don't forget to release "audioPlayer" when you're done with it.
NSString *urlAddress = [[NSBundle mainBundle] pathForResource:#"filename" ofType:#"m4a"];
NSURL *url = [NSURL fileURLWithPath:urlAddress];
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
if (audioPlayer == nil)
{
NSLog([error description]);
}
else
{
[audioPlayer play];
}
Hope this example helps you with playing audio on the actual device. It might also be a good idea to increase the device audio when the file is playing.
Note: You will need to add the AVFoundation framework to your project if you have not already done so. As well as import the header file.
#import <AVFoundation/AVFoundation.h>
Update:
From Apple's Core Audio Overview Document
Audio Session Services
Audio Session Services lets you manage audio sessions in your application—coordinating the audio behavior in your application with background applications on an iPhone or iPod touch. Audio Session Services consists of a subset of the functions, data types, and constants declared in the AudioServices.h header file in AudioToolbox.framework.
The AVAudioPlayer Class
The AVAudioPlayer class provides a simple Objective-C interface for playing sounds. If your application does not require stereo positioning or precise synchronization, and if you are not playing audio captured from a network stream, Apple recommends that you use this class for playback. This class is declared in the AVAudioPlayer.h header file in AVFoundation.framework.
Start by error-checking your returns. Is filePath nil? Do either of the AudioServices functions return an error? The most likely cause is case-sensitivity. The iPhone filesystem is case sensitive while the Mac is not. But the first step in debugging is to look at the errors the system is providing.
The simulator uses regular QuickTime for playback, so it's easy to have media assets which work in the sim, but fail on the device due to missing / unsupported codecs. The test is if you can play the file at all on the device, eg through Safari or the iPod app.