Xamarin Community Toolkit CameraView video file location supplied becomes invalid IOS and Android - xamarin

I'm using the CameraView to capture a series of short videos. I want these videos to be viewable at a later time from within the app. I'm using the MediaCaptured event to get the path of captured videos and saving these paths in a SQLite db.
The first problem is on iOS, the path is valid while the app is open, but if I close the app and open it again the path is no longer valid. I've worked around this by copying the video to the AppDataDirectory but this seems bad because I haven't figured out how to delete the original so now two copies of the video exist.
The second problem is on both iOS and Android, after some amount of time (a few days or a week or more) these paths become invalid for some unknown reason.
What is the correct way to deal with this?
private void MediaCaptured(object obj)
{
MediaCapturedEventArgs args = obj as MediaCapturedEventArgs;
string sPath = "";
switch (Device.RuntimePlatform)
{
case Device.iOS:
//On iOS args.Video.File returns a path that isn't valid when the app is restarted. To get around this issue I am copying the file to the App Data Directory.
//The drawback is there are now two video files and I can't delete the original.
var pathSplit = args.Video.File.Split('/');
sPath = Path.Combine(FileSystem.AppDataDirectory, pathSplit[pathSplit.Length - 1]);
File.Copy(args.Video.File, sPath);
//TODO Should probalby be deleting the original video but not sure how (or if its possible).
break;
case Device.Android:
sPath = args.Video.File;
break;
}
SavePathToDB(sPath);
}

Related

Setting Google Photos date

I uploaded many photos with no EXIF data, but with their date in the name. Google Photos used upload date to sort them. I'd like to use the date in their name to modify them.
So far I tried to use Drive API to change modification date, I can change it but it is not used. I also tried to modify imageMediaMetadata.date, but it seems to be read-only to me.
Code:
function myFunction() {
var files = DriveApp.getFilesByName("IMG-20150402-WA0002_1.jpg")
while (files.hasNext()) {
var file = files.next();
var name = file.getName().toUpperCase();
if (name.indexOf("-WA") > -1) {
if (name.indexOf("IMG-20") == 0 || name.indexOf("VID-20") == 0) {
var y = name.substr(4, 4);
var m = name.substr(8, 2);
var d = name.substr(10, 2);
var file2 = Drive.Files.get(file.getId());
file2.imageMediaMetadata.date = y+"-"+m+"-"+d+"T12:00:00.000Z";
var file3 = Drive.Files.patch(file2, file.getId());
Logger.log(name + " no ok " + file3.imageMediaMetadata.date); // same as file2
}
}
}
I could delete them, modify the original files and re-upload, but before that I'd like to be sure there is no other way.
Thank you.
Perhaps you could programmatically write an EXIF header to the files?
I would also be looking for a convenient way to supply photo date when uploading old photos using the new-ish Google Photos API. My photos do not necessarily have EXIF data; I tried setting the creation/last modified date on one of my JPEGs on my MacOS machines disk, then manually uploading it via the Google Photos web interface and the date of of the JPEG file on local disk becomes the photo's date in Google Photos, as expected. The file has no EXIF data and if did, it would not contain that same date, so apparently the google photos web uploader respects the local filesystem date for the photo.
I then tried to sniff the traffic using Charles Proxy, but apparently the web interface does not use the Google Photos API same way that us external developers would -- it doesnt POST to https://photoslibrary.googleapis.com/v1/uploads or so it seems. So I couldn't reverse engineer that process. Also I couldn't see where the file creation date was passed in.
What would be great is to have a HTTP header in the upload POST request to set this date. I dont see batchCreate (https://developers.google.com/photos/library/reference/rest/v1/mediaItems/batchCreate) method having any means of setting this.

File Activation in Windows Store app in C#?

I m tryin to make metro Media Player ,but I have a problem in file activation i.e when I open mp3 file from Windows explorer, it open my app But Doesn,t get Arguments, how can I get file or name of file in text block for which my app is launched,i saw many methods in different Websites,But I can't Solve,
here is a really good explanation on how to do this:
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh779669.aspx
you can get the file name and file size here:
protected override void OnFileActivated(FileActivatedEventArgs args)
{
// TODO: Handle file activation
// The number of files received is args.Files.Size
// The first file is args.Files[0].Name
}

DirectX Windows 8.1 fstream won't load file

I'm building a Windows 8.1 DirectX app and trying to load in an external to store level data.
The relevant code currently is (this method is called in the AssetHandler constructor):
void AssetHandler::LoadLevelsData()
{
unsigned int i = 0;
std::string lineData;
this->currentFile.open("Assets/reg.txt");
//Below statement here purely to check if the blasted thing is opening
if (this->currentFile.is_open())
{
i++;
}
while (std::getline(this->currentFile, lineData))
{
levels[i] = lineData;
i++;
}
currentFile.close();
}
The problem that i'm having is that the file does not appear to be opening. I have tried:
Using a full path
Opening the file in the initialisation list
A breakpoint shows that it is jumping over the if and while
I found some information saying that DirectX has constraints on working with external files but it did not specify exactly what these were.
The Item Type was set to 'Does not participate in build'. Setting this value to 'Text' solved the problem.

AU Preset (.aupreset) resource path issue in iOS LoadPresetDemo sample code

I've been working with the iOS LoadPresetDemo sample code - if loads AUPreset files to configure different types of samplers (pretty cool) - and have run into a question/issue.
The demo code runs fine but when I try to reuse the .aupreset files in test project built from scratch, the Trombone.aupreset doesn't work. Digging into it, I noticed what seems like oddness with the audio sample paths in the .aupreset file.
The paths in the plist (images below) point to:
file://localhost//Library/Audio/Sounds/Tbone/1a%23.caf
but that is not the correct path - according to the project directory structure. There are no "Library/Audio" directories - virtual or real. So I'm confused. The Apple demo works fine but my from scratch project does not (get error -43 when trying to load the samples). The code that loads the samples (at bottom) is not doing anything to relativize the paths at runtime.
Does anyone see what I am misunderstanding here? - Thanks!
// Load a synthesizer preset file and apply it to the Sampler unit
- (OSStatus) loadSynthFromPresetURL: (NSURL *) presetURL {
CFDataRef propertyResourceData = 0;
Boolean status;
SInt32 errorCode = 0;
OSStatus result = noErr;
// Read from the URL and convert into a CFData chunk
status = CFURLCreateDataAndPropertiesFromResource (
kCFAllocatorDefault,
(__bridge CFURLRef) presetURL,
&propertyResourceData,
NULL,
NULL,
&errorCode
);
NSAssert (status == YES && propertyResourceData != 0, #"Unable to create data and properties from a preset. Error code: %d '%.4s'", (int) errorCode, (const char *)&errorCode);
// Convert the data object into a property list
CFPropertyListRef presetPropertyList = 0;
CFPropertyListFormat dataFormat = 0;
CFErrorRef errorRef = 0;
presetPropertyList = CFPropertyListCreateWithData (
kCFAllocatorDefault,
propertyResourceData,
kCFPropertyListImmutable,
&dataFormat,
&errorRef
);
// Set the class info property for the Sampler unit using the property list as the value.
if (presetPropertyList != 0) {
result = AudioUnitSetProperty(
self.samplerUnit,
kAudioUnitProperty_ClassInfo,
kAudioUnitScope_Global,
0,
&presetPropertyList,
sizeof(CFPropertyListRef)
);
CFRelease(presetPropertyList);
}
if (errorRef) CFRelease(errorRef);
CFRelease (propertyResourceData);
return result;
}
I had the same Problem and after 2 hours of comparing the "load preset"-Demo with my code I found the solution:
When adding the sound-folder check the options:
Copy items
Create folder references for any added folders -- and the added folders will be blue like in the "load preset"-demo-project!
The following is from Apple Technical Note TN2283 and discusses the paths issue that was initially asked about. You will obviously need to have the Sounds Folder, your assets and preset file part of your bundle.
Technical Note TN2283 AUSampler - Loading Instruments Excerpt
When the AUSampler attempts to load audio files via the paths provided in the external file refs portion of an .aupreset file or a set of individual file URLs, it will use the following rules to resolve each path:
If the audio file is found at the original path, it is loaded.
If the audio file is NOT found, the AUSampler looks to see if a path includes a portion matching "/Sounds/", "/Sampler Files/" or "/Apple Loops/" in that order.
If the path DOES NOT include one of the listed sub-paths, an error is returned.
If the path DOES include one of the listed sub-paths, the portion of the path preceding the sub-path is removed and the following directory location constants are substituted in the following order:
Bundle Directory
NSLibraryDirectory
NSDocumentDirectory
NSDownloadsDirectory
For example, in an iOS application if the original path was "/Users/geddy/Library/Audio/Sounds/MyFavoriteHeadacheSound.caf" and this path was not found, the AUSampler would then search for the audio file in the following four places:
<Bundle_Directory>/Sounds/MyFavoriteHeadacheSound.caf
<NSLibraryDirectory>/Sounds/MyFavoriteHeadacheSound.caf
<NSDocumentDirectory>/Sounds/MyFavoriteHeadacheSound.caf
<NSDownloadsDirectory>/Sounds/MyFavoriteHeadacheSound.caf
Therefore using the above example, if you were moving a preset created on the Desktop to an iOS application you could simply place the MyFavoriteHeadacheSound.caf file in a folder called "Sounds" within your application bundle and the AUSampler will find the audio file referenced by the preset.
You need to add both presets to your target so that they are part of the bundle:
That's what the line:
NSURL *presetURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Trombone" ofType:#"aupreset"]];
says.
Also you may want to have a look at Referencing External Audio Files at the bottom of the page.

WP7 app version

A Windows Phone 7 app, it seems, has two places with version number - one in AssemblyInfo.cs (via AssemblyVersion/AssemblyFileVersion attributes), the other is WMAppManifest.xml. Those two seem uncorrelated - changing one does not affect the other. The Marketplace, it seems, uses the one from the manifest - can someone please confirm this?
The real question is - how do I retrieve the one from manifest programmatically to display on the About screen?
The WmAppManifest.xml number is in use. First two digits are relevant for Marketplace (it is checked when you do the update) next two are for your internal usage.
This is a regular XML file, open it as a XDocument and parse it. An example.
EDIT: the example is extraneous. For just the version, use:
string Version = XDocument.Load("WMAppManifest.xml")
.Root.Element("App").Attribute("Version").Value;
To get App Version from "WMappManifest.xml", this solution might be a bit more efficient than lukas solution:
For WP7:
var xmlReaderSettings = new XmlReaderSettings
{
XmlResolver = new XmlXapResolver()
};
using (var xmlReader = XmlReader.Create("WMAppManifest.xml", xmlReaderSettings))
{
xmlReader.ReadToDescendant("App");
return xmlReader.GetAttribute("Version");
}
For WP8:
using (var stream = new FileStream("WMAppManifest.xml", FileMode.Open, FileAccess.Read))
{
string appVersion = XElement.Load(stream).Element("App").Attribute("Version").Value;
}

Resources