How to play a sound from JS in a UWP app? - javascript

I'm developing a UWP that contains a WebApp that has some JS functions that invokes some C# functions. Nowadays, I'm trying to play a sound that I have stored in the Assets folder of my UWP app:
This is the function that I'm trying to play of my Windows Runtime Component:
public async void Beep()
{
await CoreApplication.MainView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
async () =>
{
MediaElement mysong = new MediaElement();
StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
StorageFolder soundsFolder = await folder.GetFolderAsync("sounds");
StorageFile file = await soundsFolder.GetFileAsync("beep.mp3");
var stream = await file.OpenAsync(FileAccessMode.Read);
mysong.SetSource(stream, file.ContentType);
mysong.Play();
});
}
By the way, I also tried this code and it didn't work too:
public async void Beep()
{
MediaElement mysong = new MediaElement();
StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
StorageFolder soundsFolder = await folder.GetFolderAsync("sounds");
StorageFile file = await soundsFolder.GetFileAsync("beep.mp3");
var stream = await file.OpenAsync(FileAccessMode.Read);
mysong.SetSource(stream, file.ContentType);
mysong.Play();
}
This is the structure of the location of the file:
And this is how I'm calling it from JS:
CallJSCSharp.Beep();
I have more functions inside the Windows Runtime Component and all of them are working as expected with exception of this one. Thanks for your help.

MediaElement needs to be added to a XAML UI tree to work; you should just use the MediaPlayer API instead. You don't even need to write C# code to do it - you should be able to access the API directly from JavaScript (if you want to). More on the Media Playback overview page

I found how to fix it:
I added both projects in the same solution:
UWP project.
Windows Runtime Component.
I removed extra code from the function (it's unnecessary to add the Media Element in the XAML as suggested before).
public async void Beep()
{
MediaElement mysong = new MediaElement();
StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
StorageFolder soundsFolder = await folder.GetFolderAsync("sounds");
StorageFile file = await soundsFolder.GetFileAsync("beep.mp3");
var stream = await file.OpenAsync(FileAccessMode.Read);
mysong.SetSource(stream, file.ContentType);
mysong.Play();
}
Important to remember when you call any JS function, it must be with lower cases because JS conventions (even if your function has been written with upper cases).
CallJSCSharp.beep();
More information about JS Conventions:
Using the Windows Runtime in JavaScript

Related

Using fetch() returns index.html (no Framework, serving with Parcel)

I am trying to build a javascript program and am serving it with Parcel during development. Using fetch() always returns the index.html.
The *.abc file is a music markdown format. The files needed will be provided by the program, not by the user (no files on the users hardrive are involved).
import abcjs from "abcjs";
async function rendering() {
let score = await fetch("./omnibook/Buzzy.abc");
let score_text = await score.text();
console.log(score_text);
let parsed = await abcjs.renderAbc("paper", score_text);
console.log(parsed);
}
rendering();
If I use light-server instead of parcel, fetch() works fine, but it can't resolve the abcjs import.

Github pages, how to fetch file in js from repo

I have a github pages project that I am trying to create. I've got it working great on local, but of course when I publish it it fails.
The problem is in this bit of javascript, which is supposed to pull some data from a json file in the repo to build the contents of a certain page:
(async function(){
const response = await fetch(`https://GITUSER.github.io/GITREPO/tree/gh-pages/data/file.json`);//Error gets thrown here, because the asset does not exist in the current code state.
const docData = await response.json();
const contentTarget = document.getElementById('doc-target');
const tocTarget = document.getElementById('toc-target')
createContent(tocTarget,contentTarget,docData);
})();
Now, the problem is that pages won't load the asset because it doesn't know that it needs it until the function is called. Is there a way to get this asset loaded by pages so it can be called by the fetch API? Or is this beyond the capabilities of github pages?
Edited: Added some additional code for context.
Try using raw.githubusercontent.com like this
(async function(){
const response = await fetch('https://raw.githubusercontent.com/{username}/{repo}/{branch}/{file}')
const docData = await response.json();
const contentTarget = document.getElementById('doc-target');
const tocTarget = document.getElementById('toc-target')
createContent(tocTarget,contentTarget,docData);
})();
And it would work

Display local html page in UWP WebView

I would like to display my local html page in a WebView. If I put my html page in the Application's local folder then I can point to it using the following code and it works:
webView.Navigate(new Uri("ms-appdata:///local/myHtmlPage.html"));
But I want to know if there is an equivalent Uri that takes my to the publisher cache folder? The reason I ask is I want to share the html page and it's data (files) between the applications I deploy. I have tried putting the html page in the publisher cache folder, then pointing the WebView's Navigate method to the html page's path but I can't get the WebView to open the page. I get some HRESULT exception with no details as to why it failed.
I want to open files in the html page without prompting the user to pick one and the only way I know how to do this is if the files are in a sub directory of the page's directory. I'll have a javascript function that opens the file using the path and I'll call this function from my UWP application and pass it the name of the file.
Help in this regard would be greatly appreciated.
Display local html page in UWP WebView
Sure, you could use StreamUriWinRTResolver to converter html file where in publisher folder to stream. And use WebView NavigateToLocalStreamUri to load that stream.
For example
public sealed class StreamUriWinRTResolver : IUriToStreamResolver
{
/// <summary>
/// The entry point for resolving a Uri to a stream.
/// </summary>
/// <param name="uri"></param>
/// <returns></returns>
public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
{
if (uri == null)
{
throw new Exception();
}
string path = uri.AbsolutePath;
// Because of the signature of this method, it can't use await, so we
// call into a separate helper method that can use the C# await pattern.
return getContent(path).AsAsyncOperation();
}
/// <summary>
/// Helper that maps the path to package content and resolves the Uri
/// Uses the C# await pattern to coordinate async operations
/// </summary>
private async Task<IInputStream> getContent(string path)
{
// We use a package folder as the source, but the same principle should apply
// when supplying content from other locations
try
{
var filename = path.Remove(0, 1);
StorageFile f = await ApplicationData.Current.GetPublisherCacheFolder("Folder1").GetFileAsync(filename);
IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
return stream.GetInputStreamAt(0);
}
catch (Exception e)
{
throw new Exception("Invalid path");
}
}
}
Usage
Uri url = MyWebView.BuildLocalStreamUri("MyTag", "ContentPage.html");
StreamUriWinRTResolver myResolver = new StreamUriWinRTResolver();
MyWebView.NavigateToLocalStreamUri(url, myResolver);

Writing a file to a bare repostory not at the root with NodeGit / LibGit2

I've been able to write a file to a branch in a bare repository using the below code, but it only works for files in the root. I haven't been able to find a good example in the documentation of how to build a tree for a subfolder and use that as a commit.
async function writeFile(filename, buffer) {
const signature = NodeGit.Signature.now('Jamie', 'jamie#diffblue.com');
const repo = await NodeGit.Repository.openBare('java-demo.git');
const commit = await repo.getBranchCommit('master');
const rootTree = await commit.getTree();
const builder = await NodeGit.Treebuilder.create(repo, rootTree);
const oid = await NodeGit.Blob.createFromBuffer(repo, buffer, buffer.length);
await builder.insert(filename, oid, NodeGit.TreeEntry.FILEMODE.BLOB);
const finalOid = await builder.write();
await repo.createCommit('refs/heads/master', signature, signature, 'Commit message', finalOid, [commit]);
}
const buffer = new Buffer('Hello\n', 'utf-8');
writeFile('test.txt', buffer).then(() => console.log('Done'));
What modifications would be needed to post in (for example) src/test.txt, instead of test.txt?
The typical workflow for writing trees goes through the index. For example, git_index_add_frombuffer followed by git_index_write_tree. Even if you don't want to write to the repository's index on disk, you can still use the index interface by creating an in-memory index.
In a bare repository without an index, you can use git_index_new followed by git_index_read_tree to get an index initialized to the contents of your tree. Then write the tree out to the repository with git_index_write_tree_to.
I'm less familiar with the treebuilder interface, but it looks like you would have to create new subtrees recursively. For example, get or create the src subtree and insert the test.txt blob into it. Then get or create the root tree and insert the src subtree into it.

Div to bitmap image? NodeJS / WinJS / anything?

Is there any way to convert a div to an image that the user can save without using other languages.
I've looked everywhere but I can't seem to find any way to render html to bitmap , not even in nodeJS or WinJS.
There are a lot of applications that could benefit from this , any reason why this can't be done without a server?
In Windows 8.1 you can load the HTML into an x-ms-webview element using its navigate or navigateToString methods, then use the webview's capturePreviewToBlobAsync method. (If you have a div, you might be able to get its innerHTML string and pass to the webview's navigateToString to load that content.)
Note that this isn't WinJS specifically, as this is a feature of the webview element. So it might not be a solution that's portable to the web generally.
In any case, here's a code snippet from an example in Chapter 4 of my free ebook (Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition) that captures a webview's contents into a bitmap which it then displays in an img element (notice how I turn the DOM-ish async call into a WinJS promise for convenience):
function captureImage() {
var webview = document.getElementById("webview");
var promise = new WinJS.Promise(function (cd, ed) {
var op = webview.capturePreviewToBlobAsync();
op.oncomplete = function (args) { cd(args.target.result); };
op.onerror = function (e) { ed(e); };
op.start();
});
promise.then(function (blob) {
document.getElementById("imgOutput").src = URL.createObjectURL(blob, { oneTimeOnly : true });
});
}
You can do whatever else you want with the blob that the promise delivers, e.g. write to a file, upload, etc. But that's how you can get the rendering in Win 8.1.

Categories

Resources