I am working on a project based on Linphone-iPhone, the project requires taking a snapshot of current video stream (both in and out).
I've found this 'linphone_call_take_video_snapshot' in liblinphone and gave it a try.
The code was simple and running without any error, but the size of the saved file is always 0 kb!
Here's the code:
- (void)capture {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *file_path = [documentsDirectory stringByAppendingPathComponent:#"snapshot.jpeg"];
LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
const char *c_file_path = [file_path cStringUsingEncoding:NSUTF8StringEncoding];
int ret = linphone_call_take_video_snapshot(call, c_file_path);
if (ret >= 0 && [[NSFileManager defaultManager] fileExistsAtPath:file_path]) {
UIImageWriteToSavedPhotosAlbum([UIImage imageWithContentsOfFile:file_path], nil,nil,nil);
}
}
Does linphone_call_take_video_snapshot really work? If so, what have I been doing wrong?
Related
Currently, I am streaming image and depth data from my iphone X and doing a series of computations on it using a compute metal kernel. The output every cycle (frame) is approximately 900,000 floats. Assuming there are 30 cycles (frames) a second, this represents 27million floats a second.
I would like to save a few seconds (3-5) of this data to a file, which I can then access later.
My current approach of writing the output every cycle is too slow (I/O is expensive) and I am not sure how to buffer the results of a few cycles correctly (I tried creating an array of arrays but then run into memory issues).
Copy data from mtl buffers:
//number of elements per frame approx 300,000
size_t len = elementCount
finalArrayX = new float [len];
finalArrayY = new float [len];
finalArrayZ = new float [len];
//MTLBuffers
finalArrayX = (float*) resultsBufferX.contents;
finalArrayY = (float*) resultsBufferY.contents;
finalArrayZ = (float*) resultsBufferZ.contents;
writeToFile(finalArrayX, finalArrayY, finalArrayZ)
writeToFile:
/*
* Get file handle to append to
*/
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentTXTPath = [documentsDirectory stringByAppendingPathComponent:#"test.txt"];
if(![[NSFileManager defaultManager] fileExistsAtPath: documentTXTPath]) {
[[NSFileManager defaultManager] createFileAtPath: documentTXTPath contents:nil attributes:nil];
}
NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:documentTXTPath];
[myHandle seekToEndOfFile];
/*
* Create strings and write line by line
*/
for(int k = 0; k < elementCount; k ++){
NSString *x_i = [NSString stringWithFormat:#"%.2f", finalArrayX[k]];
NSString *y_i = [NSString stringWithFormat:#"%.2f", finalArrayY[k]];
NSString *z_i = [NSString stringWithFormat:#"%.2f", finalArrayZ[k]];
NSString *temp = [line stringByAppendingString: x_i];
temp = [temp stringByAppendingString: #" "];
NSString *tempTwo = [temp stringByAppendingString: y_i];
tempTwo = [tempTwo stringByAppendingString: #" "];
NSString *tempThree = [tempTwo stringByAppendingString: z_i];
NSString *totalLine = [tempThree stringByAppendingString: #"\n"];
[myHandle writeData:[totalLine dataUsingEncoding:NSUTF8StringEncoding]];
}
Whats the best way to go about this?
I am using ZipArchive and am reading data in from a device. What I want to do is take the data from the device and unzip it. The only examples I can find are taking the data, writing it to a file on the iOS device, and reading (unzipping) it back again...
This is the code (not working) that I have writing it to disk...
// Read the data in...
if ((recvStringLen = recvfrom(connectSock, recvString, 1025, 0, (struct sockaddr *)&broadcastAddr, &recvStringLen)) < 0) {
NSLog(#"ERROR: Unable to receive user perms message.");
[self showTimeoutError];
return -1;
}
// get the file size...
unsigned int fileSize = (( recvString[16] << 24 ) & 0xff000000) |
(( recvString[17] << 16 ) & 0xff0000) |
(( recvString[18] << 8 ) & 0xff00 ) |
( recvString[19] & 0xff );
NSLog(#"fileSize: %i", fileSize);
recvString[20+fileSize] = '\0'; // terminate the string...
// convert the char data to a string
NSString *stringData = [[[NSString alloc] initWithFormat:#"%s", &recvString[20]] autorelease];
NSData *data = [[[NSData alloc] initWithBytes:stringData length:fileSize] autorelease];
// write the data...
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"userinfo.zip"];
[data writeToFile:appFile atomically:YES];
// exist?
BOOL zipExists = [[NSFileManager defaultManager] fileExistsAtPath:appFile];
NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:#"userinfo.zip"];
NSString *output = [documentsDirectory stringByAppendingPathComponent:#"userinfo.dat"];
ZipArchive* za = [[ZipArchive alloc] init];
// unzip it...
BOOL success = [za UnzipOpenFile:zipFilePath];
if( success ) {
BOOL outSuccess = [za UnzipFileTo:output overWrite:YES];
if( outSuccess != NO ) {
NSLog(#"success");
}
[za UnzipCloseFile];
}
[za release];
BOOL datExists = [[NSFileManager defaultManager] fileExistsAtPath:output];
When it gets to 'success', it is always NO... even though 'zipExists' is YES.
The two issues I have:
1. The I haven't successfully written the data to disk, read it back, and unzipped it.
2. I would rather just unzip the data (NSData) instead of going thru writing it to disk and reading it back again...
I searched before posting, but was unable to find a solution...
Skip creating a NSString - that is your problem (or one of them). Create the data object from recvString directly. Think about what happens using %s if the data has a null byte.
I have downloaded a file(ZipSecretExcel.zip) which is stored in the document directory. I am now trying to unzip this file in the document directory using ZipArchieve using the following code:
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:#"ZippSecretExcel.zip"];
NSString *output = [documentsDirectory stringByAppendingPathComponent:#"UnZipSecret"];
ZipArchive* za = [[ZipArchive alloc] init];
if( [za UnzipOpenFile:zipFilePath] ) {
if( [za UnzipFileTo:output overWrite:YES] != NO ) {
//unzip data success
//do something
//NSLog(#"Folder successfully zipped");
}
[za UnzipCloseFile];
}
However, folder successfully zipped log message never gets printed which means there is failure in unzipping. Can anyone tell what is that I am doing wrong?
This is the first time I'm trying to create and access a SQLite db in iOS and I followed a tutorial, but I can't make this work. These are the steps I've followed:
Created a database through the Firefox plugin ("testDatabase") and a
table ("testTable") with several columns
Saved the "testDatabase.sqlite" file in a directory
Dragged and dropped such file into my "Supporting Files" group in my
Xcode project
Added "libsqlite3.dylib" in Build Phases > Link Binary With
Libraries
Added "-lsqlite3" in Build Settings > Linking > Other Linker Flags >
Debug and Release
In a ViewController, called this method:
-(NSString *)copyDatabaseToDocuments {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"testDatabase.sqlite"];
if ( ![fileManager fileExistsAtPath:filePath] ) {
NSString *bundlePath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"testDatabase.sqlite"];
[fileManager copyItemAtPath:bundlePath toPath:filePath error:nil];
}
return filePath;
}
Then, trying to write in the database:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"testDatabase.sqlite"];
sqlite3 *database;
if(sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "insert into testTable (id) VALUES (?)";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
sqlite3_bind_int(compiledStatement, 1, newObject.ID);
}
if(sqlite3_step(compiledStatement) == SQLITE_DONE) {
sqlite3_finalize(compiledStatement);
}
}
sqlite3_close(database);
I have read several posts regarding a similar error, but nothing of what I tried has worked for me... I also tried with NSString *filePath = [[NSBundle mainBundle] pathForResource:#"testDatabase" ofType:#"sqlite"]; but it is null, and also have underplayed and redeployed my app in the simulator several times...
Thanks in advance
I finally got this working by simply deleting the app folder generated in /Users/[user]/Library/Application Support/iPhone Simulator/5.1/Applications/ to be created again when running the simulator
I am trying to to make a connection to a database and I'm finding that it is successful when I make the path go to NSBundle, but not when I try make the path be in my app's documents directory. Here is my code:
-(IBAction)setInput:(id)sender
{
NSString *strStoreNumber;
NSString *strRegNumber;
strStoreNumber = StoreNumber.text;
strRegNumber = RegNumber.text;
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths lastObject];
NSString* databasePath = [documentsDirectory stringByAppendingPathComponent:#"tblStore.sqlite"];
// NSString* databasePath = [[NSBundle mainBundle] pathForResource:#"tblStore" ofType:#"sqlite"];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"Opened sqlite database at %#", databasePath);
sqlite3_exec(database, "CREATE TABLE IF NOT EXISTS tblStore (ID INTEGER PRIMARY KEY AUTOINCREMENT, Message TEXT)", NULL, NULL, NULL);
//...stuff
}
else
{
NSLog(#"Failed to open database at %# with error %s", databasePath, sqlite3_errmsg(database));
sqlite3_close (database);
}
//
NSString *querystring;
// create your statement
querystring = [NSString stringWithFormat:#"SELECT strStore, strReg FROM tblStore WHERE strStore = %# AND strReg = %#;", strStoreNumber, strRegNumber];
const char *sql = [querystring UTF8String];
NSString *szStore = nil;
NSString *szReg = nil;
sqlite3_stmt *statement = nil;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL)!=SQLITE_OK) //queryString = Statement
{
NSLog(#"sql problem occured with: %s", sql);
NSLog(#"%s", sqlite3_errmsg(database));
}
else
{
// you could handle multiple rows here
while (sqlite3_step(statement) == SQLITE_ROW)
{
szStore = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)];
szReg = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)];
}
}
sqlite3_finalize(statement);
lblStoreNumber.text = szStore;
lblRegNumber.text = szReg;
//
}
I commented out the line:
NSString* databasePath = [[NSBundle mainBundle] pathForResource:#"tblStore" ofType:#"sqlite"];
When this line is NOT commented out, and the lines above it ARE commented out:
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths lastObject];
NSString* databasePath = [documentsDirectory stringByAppendingPathComponent:#"tblStore.sqlite"];
Then it works fine. However, if those three lines are not commented out (as shown in the setInput method, then I get the following errors:
2012-05-07 13:44:29.511 CCoDBTry[1981:f803] Opened sqlite database at /Users/Matt****/Library/Application Support/iPhone Simulator/5.1/Applications/5DB7A218-A0F6- 485F-B366-91FD2F9BC062/Documents/tblStore.sqlite
2012-05-07 13:44:29.545 CCoDBTry[1981:f803] sql problem occured with: SELECT strStore, strReg FROM tblStore WHERE strStore = 8053 AND strReg = 4;
2012-05-07 13:44:29.546 CCoDBTry[1981:f803] no such column: strStore
Keep in mind, this same database table is accessed and works just fine when I use the NSBundle logic. I admit I don't fully understand the difference between NSBundle and documentsDirectory, but I think I would want my table to exist in my app's documents. I would greatly appreciate any help on this.
Thanks!
NSBundle is used to access resources within your application itself: that is, everything inside YourApp.app. The documentsDirectory is a location outside of your app -- it's in the "home directory" which is part of your app sandbox, and which is analogous to your user home directory on the Mac.
These are different locations, so using one to find a file at the same subpath of another won't work.
What #rickster is saying is this:
If you add the sqlite database to your project in Xcode, the database's file gets added to your app's bundle.
If you create the database in code, the file will (most likely) get created in your documents directory (but surely not in your bundle).
The two locations are completely separate. Your bundle is created when your app is compiled and cannot be changed later. Your documents directory is "sandboxed", which allows you access to it; you can read/write/delete files here.
Copy from NSBUndle TO NSDocumentDirectory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"culinary-Info.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"culinary-Info" ofType:#"sqlite"];
[fileManager copyItemAtPath:bundle toPath:path error:nil];
}