I'm creating a SKVideoNode in the following way. It creates the video without any issues, but I get this strange log message and I'm wondering if anyone knows what it's all about. I tried googling it, but I couldn't find anything.
Here's the error:[22:48:15.170] vtFindDynamicSession signalled err=-11204 (err) (registered pixel transfer service failed to open; falling back) at /SourceCache/CoreMedia_frameworks/CoreMedia-1562.240/Sources/VideoToolbox/VTPixelTransferSession.c line 6878
GameScene.m
#import "GameScene.h"
#import <AVFoundation/AVFoundation.h>
#interface GameScene()
#property SKVideoNode *vid;
#property AVPlayer *avPlayer;
#end
#implementation GameScene
-(void)didMoveToView:(SKView *)view {
NSString *fileName = #"QSeanRay";
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDesktopDirectory, NSUserDomainMask, YES);
NSString *desktopPath = [paths objectAtIndex:0];
NSString *resourcePath = [NSString stringWithFormat:#"%#/vs", desktopPath];
NSString *videoPath = [NSString stringWithFormat:#"%#/%#.mp4", resourcePath, fileName];
NSURL *fileURL = [NSURL fileURLWithPath:videoPath];
AVPlayer *avPlayer = [[AVPlayer alloc] initWithURL:fileURL];
_vid = [SKVideoNode videoNodeWithAVPlayer:avPlayer];
_vid.position = CGPointMake(view.bounds.size.width/2, view.bounds.size.height/2);
[_vid setScale:0.4];
[self addChild:_vid];
[_vid play];
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[avPlayer currentItem]];
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
[p seekToTime:kCMTimeZero];
}
#end
Related
A very common question but I can't figure out what I'm doing wrong in playing a simple audio file in iOS 10 and 9. I have the following code:
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
NSString *soundFilePath = [NSString stringWithFormat:#"%#",[[NSBundle mainBundle] pathForResource:#"www/sounds/ringbacktone" ofType:#"mp3"]];
[self playTone:soundFilePath Loop:YES];
-(void) playTone:(NSString *) soundFilePath Loop:(BOOL) loop{
NSLog(#"Sound File Path: %#",soundFilePath);
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:soundFilePath]){
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSError *error = nil;
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
if (error){
NSLog(#"Error creating the audio player: %#",error);
}else{
if (loop == YES)
player.numberOfLoops = -1; //Infinite
[player setVolume:1.0];
[player play];
}
}else{
NSLog(#"No sound will be played. The file doesn't exist.");
}
}
The output is
Sound File Path: /var/containers/Bundle/Application/E8CCA88C-B6AB-4C36-9426-EFBB94E1D509/myapp.app/www/sounds/myfile.mp3
The file exists so the sound should play. I've tried wav,m4a and mp3 files without success.
I'm using the function before calling pjsip library. Not sure if it plays a role.
Any thoughts? Is there any other way to debug it further?
check this solution it may work :
1.create property for ur audio player:
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
2.write delegate methods for player: AVAudioPlayerDelegate
3.implement this in ur action :
yourSoundArray=[NSArray arrayWithObjects:#"sound1",#"sound2",#"sound3",#"sound4",#"sound5",#"sound6", nil];//dont include formate type
NSString *audioPath = [[NSBundle mainBundle] pathForResource: [yourSoundArray objectAtIndex:indexPath.row] ofType:#"mp3"];
NSLog(#"%#",audioPath);
NSURL *audioURL = [NSURL fileURLWithPath:audioPath];
NSError *audioError = [[NSError alloc] init];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&audioError];
audioPlayer.delegate=self;
if (!audioError) {
NSLog(#"playing!");
audioPlayer play];
}
else {
NSLog(#"Error!");
}
check the audio player-delegate action
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{ NSLog(#"%d",playing the audio);
}
The answer was a combination of these:
in .h file I had to inherit from AVAudioPlayerDelegate, i.e.
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#interface scAudioManager : NSObject <AVAudioPlayerDelegate>{
#property (strong, nonatomic) AVAudioPlayer *player;
}
And then in .m file:
NSString *soundFilePath = [NSString stringWithFormat:#"%#",[[NSBundle mainBundle] pathForResource:#"www/sounds/ringbacktone" ofType:#"mp3"]];
[self playTone:soundFilePath Loop:YES];
-(void) playTone:(NSString *) soundFilePath Loop:(BOOL) loop{
NSLog(#"Sound File Path: %#",soundFilePath);
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:soundFilePath]){
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSError *error = nil;
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
if (error){
NSLog(#"Error creating the audio player: %#",error);
}else{
if (loop == YES)
_player.numberOfLoops = -1; //Infinite
_player.volume=[[AVAudioSession sharedInstance] outputVolume];
_player.delegate = self;
[_player prepareToPlay]
[_player play];
}
}else{
NSLog(#"No sound will be played. The file doesn't exist.");
}
}
I want to save AVAudioFile to document directory with NSDictionary. Can anyone help me?
AVAudioFile *audiofile=[[AVAudioFile alloc] initForWriting:destinationURL settings:settings error:&error];
save this audio file to document directory...
Path to the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
Saving the audio file to the documents directory:
BOOL status = [NSDictionary writeToFile:filePath atomically:YES];
if(status){
NSLog(#"File write successfully");
}
- (NSString *) dateString
{
// return a formatted string for a file name
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"ddMMMYY_hhmmssa";
return [[formatter stringFromDate:[NSDate date]]stringByAppendingString:#".aif"];
}
It saves below as in Documents
23Aug16_044104PM.aif
Why we save above like is we can differenciate the previous one next one by time.So we can't confuse now.
ViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController : UIViewController<AVAudioSessionDelegate,AVAudioRecorderDelegate, AVAudioPlayerDelegate>
{
NSURL *temporaryRecFile;
AVAudioRecorder *recorder;
AVAudioPlayer *player;
}
- (IBAction)actionRecordAudion:(id)sender;
- (IBAction)actionPlayAudio:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];
[recorder setDelegate:self];
}
- (IBAction)actionRecordAudion:(id)sender
{
NSError *error;
// Recording settings
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
[settings setValue: [NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[settings setValue: [NSNumber numberWithFloat:8000.0] forKey:AVSampleRateKey];
[settings setValue: [NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];
[settings setValue: [NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[settings setValue: [NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[settings setValue: [NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
[settings setValue: [NSNumber numberWithInt: AVAudioQualityMax] forKey:AVEncoderAudioQualityKey];
NSArray *searchPaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex: 0];
NSString *pathToSave = [documentPath_ stringByAppendingPathComponent:[self dateString]];
NSLog(#"the path is %#",pathToSave);
// File URL
NSURL *url = [NSURL fileURLWithPath:pathToSave];//FILEPATH];
//Save recording path to preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setURL:url forKey:#"Test1"];
[prefs synchronize];
// Create recorder
recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
[recorder prepareToRecord];
[recorder record];
}
- (IBAction)actionPlayAudio:(id)sender
{
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
//Load recording path from preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
temporaryRecFile = [prefs URLForKey:#"Test1"];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:temporaryRecFile error:nil];
player.delegate = self;
[player setNumberOfLoops:0];
player.volume = 1;
[player prepareToPlay];
[player play];
}
Record and Save Audio Permanently
Record Audio File and save Locally
Just now I tried the below code with iPhone 4s and it works perfectly.
AudioViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface AudioViewController : UIViewController<AVAudioSessionDelegate,AVAudioRecorderDelegate,AVAudioPlayerDelegate>
- (IBAction)actionRecordAudio:(id)sender;
- (IBAction)actionPlayAudio:(id)sender;
- (IBAction)actionStopAudio:(id)sender;
#property (strong, nonatomic) AVAudioRecorder *audioRecorder;
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
#end
AudioViewController.m
#import "AudioViewController.h"
#interface AudioViewController ()
#end
#implementation AudioViewController
#synthesize audioPlayer,audioRecorder;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
NSString *soundFilePath = [docsDir stringByAppendingPathComponent:#"sound.caf"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSDictionary *recordSettings = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityMin],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16],
AVEncoderBitRateKey,
[NSNumber numberWithInt: 2],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];
NSError *error = nil;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
audioRecorder = [[AVAudioRecorder alloc]initWithURL:soundFileURL settings:recordSettings error:&error];
if (error)
{
NSLog(#"error: %#", [error localizedDescription]);
}
else {
[audioRecorder prepareToRecord];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionRecordAudio:(id)sender
{
if (!audioRecorder.recording)
{
[audioRecorder record];
}
}
- (IBAction)actionPlayAudio:(id)sender
{
if (audioRecorder.recording)
{
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioRecorder.url
error:&error];
audioPlayer.delegate = self;
if (error)
NSLog(#"Error: %#",
[error localizedDescription]);
else
[audioPlayer play];
}
}
- (IBAction)actionStopAudio:(id)sender
{
if (audioRecorder.recording)
{
[audioRecorder stop];
}
else if (audioPlayer.playing) {
[audioPlayer stop];
}
}
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
}
-(void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
{
NSLog(#"Decode Error occurred");
}
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
}
-(void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error
{
NSLog(#"Encode Error occurred");
}
#end
Here is source
I retrieve all data from an sqlite database. I can get them to populate the table view. When I click on a row the webview opens but doesn't show the pdf file.The view is just plain white background. no crash, no errors, simply doesn't show anything.
This is my code. Not sure what I'm doing wrong.
#import "PdfTableVC.h"
#import "PdfVC.h"
#interface PdfTableVC ()
#end
#implementation PdfTableVC {
NSMutableArray *listOfPdf;
}
#synthesize pdfTable;
- (void)viewDidLoad {
[super viewDidLoad];
[self initDatabase];
[self getPoints];
}
#pragma mark - View lifecycle
-(void)initDatabase{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"my.db"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success)
{
return;
}
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"my.db"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success)
{
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
-(void)getPoints{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"my.db"];
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK)
{
const char *sql = "SELECT * FROM file_geositi";
sqlite3_stmt *searchStatement;
if (sqlite3_prepare_v2(database, sql, -1, &searchStatement, NULL) == SQLITE_OK)
{
listOfPdf = [[NSMutableArray alloc] init];
while (sqlite3_step(searchStatement) == SQLITE_ROW)
{
NSString *pdf = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement,0)];
[listOfPdf addObject:pdf];
}
}
sqlite3_finalize(searchStatement);
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [listOfPdf count];
}
//Table View cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier =#"pdfCell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if(cell == nil){
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [listOfPdf objectAtIndex:indexPath.row];
return cell;
}
//Detail View items
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showPDF"]) {
NSIndexPath *indexPath = [self.pdfTable indexPathForSelectedRow];
PdfVC *destViewController = (PdfVC *)segue.destinationViewController;
destViewController.dataPdf= [listOfPdf objectAtIndex:indexPath.row];
}
}
PdfVC.h
#import <UIKit/UIKit.h>
#interface PdfVC : UIViewController
//UIWebView
#property (nonatomic, strong) IBOutlet UIWebView *webView;
#property (nonatomic, strong) NSString *dataPdf;
#end
PdfVC.m
#import "PdfVC.h"
#interface PdfVC ()
#end
#implementation PdfVC
#synthesize webView;
#synthesize dataPdf;
- (void)viewDidLoad {
[super viewDidLoad];
//No sure about this and in fact makes the app crash
NSString *pdfName = [NSString stringWithFormat:#"%#", [self.dataPdf description]];
NSString *path = [[NSBundle mainBundle] pathForResource:pdfName ofType:#"pdf"];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
}
#end
Any help? Thanx
Ok, so after having a look at your code, I found the following things:
You are storing your PDF names in a SQLite database (I don't really
understand the purpose of doing this, but let's say you need to) with
the names 'pdf_1', 'pdf_2' and 'pdf_3', but these are not matching
with your actual file names of PDF's in your supporting files folder
which are 'PDF 1' etc.
Secondly, you are passing just the name of the PDF extracted from the database onto the PdfVC, which actually does nothing, you have to actually load the PDF into the webView here, so it actually does nothing.
Solution:
Rename your PDF's from 'PDF 1' etc to 'pdf_1' etc. so that they match with the actual names stored in your database, or rename the entries in your database to match the file names of the PDF.
Secondly, place the following code into your viewDidLoad method of the PdfVC view controller:
NSString *path = [[NSBundle mainBundle] pathForResource:dataPdf ofType:#"pdf"];
NSURL *targetURL = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
[webView loadRequest:request];
All this code is doing is that it picks up the right PDF from the resources using the name stored in the property dataPdf (passed via the segue) and then loads that PDF into the webView.
I would recommend you to re-consider the purpose of an actual database here, since all you are doing is storing the names of the PDF's into the table. It may not be required at all, and you could maintain an NSArray of the PDF names in your PDFTableVC view controller.
Hope this answers your question.
I am calling this ViewController from another UITableViewController which pass the the song name and index.For the very first time it play the song but when i go back to the tableView and click another song it play both songs simultaneously.
In .h file I used AVAudioPlayer
#property (nonatomic, strong) AVAudioPlayer *audioPlayer;
In .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
[self sliderValueChanged:volumeSlider];
[self updateTime];
[self playOrPauseSound:nil];
volumeSlider.value=0.5;
count=songArray.count;
[self setupAVPlayerForURL:songIndex];
_audioPlayer.delegate=self;
}
-(void) setupAVPlayerForURL: (int) url {
NSString *songname=[NSString stringWithFormat:#"%#",songArray[songIndex]];
songTitle.text=songname;
NSString* saveFileName = songname;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:saveFileName];
NSURL *url1 = [[NSURL alloc] initFileURLWithPath: path];
self.audioPlayer=[[AVAudioPlayer alloc] initWithContentsOfURL:url1 error:NULL];
[self.audioPlayer play];
self.seekBarSlider.minimumValue = 0.0f;
self.seekBarSlider.maximumValue = self.audioPlayer.duration;
[self updateTime];
self.isPlaying=YES;
_audioPlayer.delegate=self;
[_audioPlayer addObserver:self forKeyPath:#"status" options:0 context:nil];
}
Maybe you have to check if the audioplayer is already playing before lauch another song
if(self.audioplayer && [self.audioplayer isPlaying]){
[self.audioplayer stop];
}
I have an app that allows the user to choose a picture from their camera roll, and display it in a UIImageView. I usually use this method to save text in text fields, and I assumed that it would work for an image as well, but I'm having some issues with it. There are no errors, but it simply does not save the image.
This is the relevant code I'm using:
.h:
#define kFilename9 #"PGdata.plist"
...
- (NSString *)dataFilePath;
.m:
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFilename9];
}
- (void)applicationDidEnterBackground:(NSNotification *)notification {
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:image.image];
[array writeToFile:[self dataFilePath] atomically:YES];
}
- (void)viewDidLoad
{
...
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
image.image = [array objectAtIndex:0];
}
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:app];
[super viewDidLoad];
}
You have to convert the UIImage to a PNG or JPG first, using UImagePNGRepresentation or UIImageJPEGRepresentation. Those function return NSData which you can then write to a file.
You can save by following this way。
UIImage * image;//the image you want to save
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir=[paths objectAtIndex:0];
NSFileManager *filemanager=[NSFileManager defaultManager];
NSData * imagedata=UIImageJPEGRepresentation(image,1);
NSString *savePath= [docDir stringByAppendingPathComponent:#"imageName.jpg"];
BOOL isdic=NO;
BOOL isHave=[filemanager fileExistsAtPath:savePath isDirectory:&isdic];
if (isHave==YES&&isdic==NO) {
[filemanager removeItemAtPath:savePath error:nil];
}
BOOL result= [imagedata writeToFile:savePath atomically:YES];