Downloading Media File programmatically in Windows Phone 8 - audio

Our app is video/audio based app, and we have uploaded all the media on Windows Azure.
However it is required to facilitate user to download audio/video file on demand, so that they can play it locally.
So i need to download audio/video file programmatically and save it in IsolatedStorage.
We have Windows Azure Media File Access URLs for each audio/video. But I am stuck in 1st step of downloading media file.
I googled and came across this article, but for WebClient there is no function DownloadFileAsync that I can use.
However I tried its other function DownloadStringAsyn, and download media file is in string format but don't know how to convert it to audio(wma)/video(mp4) format. Please suggest me, how can I proceed? Is there other way to download media file?
Here is sample code that I used
private void ApplicationBarMenuItem_Click_1(object sender, EventArgs e)
{
WebClient mediaWC = new WebClient();
mediaWC.DownloadProgressChanged += new DownloadProgressChangedEventHandler(mediaWC_DownloadProgressChanged);
mediaWC.DownloadStringAsync(new Uri(link));
mediaWC.DownloadStringCompleted += new DownloadStringCompletedEventHandler(mediaWC_DownloadCompleted);
}
private void mediaWC_DownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Cancelled)
MessageBox.Show("Downloading is cancelled");
else
{
MessageBox.Show("Downloaded");
}
}
private void mediaWC_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
statusbar.Text = status= e.ProgressPercentage.ToString();
}

For downloading binary data, use [WebClient.OpenReadAsync][1]. You can use it to download data other than string data.
var webClient = new WebClient();
webClient.OpenReadCompleted += OnOpenReadCompleted;
webClient.OpenReadAsync(new Uri("...", UriKind.Absolute));
private void OnOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
}

Save this in your toolbox :)
public static Task<Stream> DownloadFile(Uri url)
{
var tcs = new TaskCompletionSource<Stream>();
var wc = new WebClient();
wc.OpenReadCompleted += (s, e) =>
{
if (e.Error != null) tcs.TrySetException(e.Error);
else if (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};
wc.OpenReadAsync(url);
return tcs.Task;
}

Related

Blazor server side upload file to Azure Blob Storage

I am using a file upload component that posts the file to an API controller and this works ok but i need to get the progres of the upload.
[HttpPost("upload/single")]
public async Task SingleAsync(IFormFile file)
{
try
{
// Azure connection string and container name passed as an argument to get the Blob reference of the container.
var container = new BlobContainerClient(azureConnectionString, "upload-container");
// Method to create our container if it doesn’t exist.
var createResponse = await container.CreateIfNotExistsAsync();
// If container successfully created, then set public access type to Blob.
if (createResponse != null && createResponse.GetRawResponse().Status == 201)
await container.SetAccessPolicyAsync(Azure.Storage.Blobs.Models.PublicAccessType.Blob);
// Method to create a new Blob client.
var blob = container.GetBlobClient(file.FileName);
// If a blob with the same name exists, then we delete the Blob and its snapshots.
await blob.DeleteIfExistsAsync(Azure.Storage.Blobs.Models.DeleteSnapshotsOption.IncludeSnapshots);
// Create a file stream and use the UploadSync method to upload the Blob.
uploadFileSize = file.Length;
var progressHandler = new Progress<long>();
progressHandler.ProgressChanged += UploadProgressChanged;
using (var fileStream = file.OpenReadStream())
{
await blob.UploadAsync(fileStream, new BlobHttpHeaders { ContentType = file.ContentType },progressHandler:progressHandler);
}
Response.StatusCode = 400;
}
catch (Exception e)
{
Response.Clear();
Response.StatusCode = 204;
Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "File failed to upload";
Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = e.Message;
}
}
private double GetProgressPercentage(double totalSize, double currentSize)
{
return (currentSize / totalSize) * 100;
}
private void UploadProgressChanged(object sender, long bytesUploaded)
{
uploadPercentage = GetProgressPercentage(uploadFileSize, bytesUploaded);
}
I am posting this file and it does upload but the file upload progress event is inaccurate it says the file upload is complete after a few seconds when in reality the file takes ~90 secs on my connection to appear in the Azure Blob Storage container.
So in the code above i have the progress handler which works (I can put a break point on it and see it increasing) but how do I return this value to the UI?
I found one solution that used Microsoft.AspNetCore.SignalR but I can't manage to integrate this into my own code and I'm not even sure if I'm on the right track.
using BlazorReportProgress.Server.Hubs;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System.Threading;
namespace BlazorReportProgress.Server.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class SlowProcessController : ControllerBase
{
private readonly ILogger<SlowProcessController> _logger;
private readonly IHubContext<ProgressHub> _hubController;
public SlowProcessController(
ILogger<SlowProcessController> logger,
IHubContext<ProgressHub> hubContext)
{
_logger = logger;
_hubController = hubContext;
}
[HttpGet("{ClientID}")]
public IEnumerable<int> Get(string ClientID)
{
List<int> retVal = new();
_logger.LogInformation("Incoming call from ClientID : {ClientID}", ClientID);
_hubController.Clients.Client(ClientID).SendAsync("ProgressReport", "Starting...");
Thread.Sleep(1000);
for (int loop = 0; loop < 10; loop++)
{
_hubController.Clients.Client(ClientID).SendAsync("ProgressReport", loop.ToString());
retVal.Add(loop);
Thread.Sleep(500);
}
_hubController.Clients.Client(ClientID).SendAsync("ProgressReport", "Done!");
return retVal;
}
}
}
I read the Steve Sandersen blog but this says not to use the code as its been superceded by inbuilt blazor functionality.
My application is only for a few users and so i'm not too worried about backend APIs etc, If the upload component used a service not a controller I could more easily get the progress, but the compoents all seem to post to controllers.
Can anyone please enlighten me as to the best way to solve this?

Calling Azure IoT File Upload from Android KitKat is returning BAD_FORMAT

I am trying to upload a .png file to Azure IoT Hubs, but for some reason I am constantly getting BAD_FORMAT. I am using com.microsoft.azure.sdk.iot:iot-device-client:1.14.2 library as I need to using an android device that is quite old (KitKat version).
The code I am using:
public void btnFileUploadOnClick(View v) throws URISyntaxException, IOException
{
Log.i("IoT App","Uploading file to IoT Hub...");
EditText text = (EditText)findViewById(R.id.editTextFileName);
String fullFileName = text.getText().toString();
try
{
File directory = Environment.getExternalStorageDirectory();
File file = new File(directory, "payments.json");
InputStream inputStream = new FileInputStream(file);
long streamLength = file.length();
if(file.isDirectory())
{
throw new IllegalArgumentException(fullFileName + " is a directory, please provide a single file name, or use the FileUploadSample to upload directories.");
}
else
{
client.uploadToBlobAsync("payments", inputStream, streamLength, new FileUploadStatusCallBack(), null);
}
Log.i("IoT App","File upload started with success");
Log.i("IoT App","Waiting for file upload callback with the status...");
}
catch (Exception e)
{
Log.e("IoT App","Exception while sending event: " + e.getMessage());
}
}
protected class FileUploadStatusCallBack implements IotHubEventCallback
{
public void execute(IotHubStatusCode status, Object context)
{
Log.i("IoT App","IoT Hub responded to file upload operation with status " + status.name());
TextViewControl.log("IoT Hub responded to file upload operation with status " + status.name());
}
}
I have the file payments.json in the device (emulator).
Any help would be appreciated!
It seems I just needed to import a separate library for accessing blob storage. Had to add the following to my gradle script:
implementation 'com.microsoft.azure.android:azure-storage-android:2.0.0'

How to bundle sounds with Codename One?

I want to include sounds in my Codename One app for effects like clicking a button, transitions, etc. I prefer not to download them from URL, since they are very small and I want them to be played even when the device is not connected to the internet. It looks like I cannot include the source files in the theme. What should I do?
Put the sound file in the "src" folder inside your project folder and reference it like below:
private Media MEDIA = null;
public void playAudio(String fileName) {
try {
if (MEDIA == null) {
final InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/" + fileName);
MEDIA = MediaManager.createMedia(is, "audio/mp3", new Runnable() {
#Override
public void run() {
MEDIA = null;
}
});
}
if (MEDIA != null && MEDIA.isPlaying() == false) {
MEDIA.setVolume(100);
MEDIA.play();
}
} catch (IOException ioe) {
}
}
...
playAudio("my_sound.mp3");

View cloudinary images/vid through android app

I have looked in so many places on a lead on how or if it is possible to view images uploaded to cloudinary, by a specific tag through Android studio app i am trying to build.
I was able to implement the upload option by user, with adding a tag to the images, and public id, also retrieving these information, but i cant find anything on how to view these images, for example i want the app to be able to view all images with a specific tag ( username ) to the user that uploaded the pictures, and could delete them ? and also view other images uploaded by other user with no other permission.
Is it possible and how !?
I ended up with this code, and i encountered a problem;
#Override
public void onClick(View v) {
new JsonTask().execute("http://res.cloudinary.com/cloudNAme/video/list/xxxxxxxxxxxxxxxxxxx.json");
// uploadExtract();
}
});
public class JsonTask extends AsyncTask<String ,String,String> {
#Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
In the log i get the following;
03-28 12:36:14.726 20333-21459/net.we4x4.we4x4 W/System.err: java.io.FileNotFoundException: http://res.cloudinary.com/we4x4/video/list/3c42f867-8c3a-423b-89e8-3fb777ab76f8.json
i am not sure if my understanding is correct of the method or i am doing something wrong ? since in the Admin API Docs. or cloudinary the syntax for the HTML request and also in the suggested page by Nadav:
https://support.cloudinary.com/hc/en-us/articles/203189031-How-to-retrieve-a-list-of-all-resources-sharing-the-same-tag-
this should've returned a JSON ?
The following feature allows you to retrieve a JSON formatted list of resources that which share a common tag:
https://support.cloudinary.com/hc/en-us/articles/203189031-How-to-retrieve-a-list-of-all-resources-sharing-the-same-tag-
Note that image removal will coerce you to use server-side code (e.g. JAVA), since deleting via Cloudinary requires a signature that is based on your API_SECRET.

Creating a local database in windows phone app 8 using vs2012

I want to develop an app in windows phone 8.
I am totally new to this. I want to create a database for that app from which I can perform CRUID Operations.
I found some information while browsing and watching videos but I did't understand much of it.
Some Steps I did:
Installed windows phone app 8 sdk for vs2012
Added some Sqlite extension from Manage Nuget Packages.
Developed a basic interface for the app.
Copied and pasted the code with few changes
What I want:
Permanently Insert and Fetch data from database (I had downloaded a code from some website but after running it when I close the emulator and try to view the data previously entered, it won't return it)
Like it should be stored in phone memory or any such place
Display the fetched data in listview or grid
Please send me the link that i can go through or any such resembling question asked here
The MainPage.xaml.cs Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using CustomerPhoneApp.Resources;
using SQLite;
using System.IO;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Popups;
using System.Data.Linq;
using System.Diagnostics;
namespace CustomerPhoneApp
{
public partial class MainPage : PhoneApplicationPage
{
[Table("Users")]
public class User
{
[PrimaryKey, Unique]
public string Name { get; set; }
public string Age { get; set; }
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
try
{
var path = ApplicationData.Current.LocalFolder.Path + #"\users.db";
var db = new SQLiteAsyncConnection(path);
await db.CreateTableAsync<User>();
}
catch (Exception)
{
}
}
// Constructor
public MainPage()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
if (txtName.Text != "" && txtAge.Text != "")
{
var path = ApplicationData.Current.LocalFolder.Path + #"\users.db";
var db = new SQLiteAsyncConnection(path);
var data = new User
{
Name = txtName.Text,
Age = txtAge.Text,
};
int x = await db.InsertAsync(data);
}
else
{
MessageBox.Show("enter the title and Notes");
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
RetriveUserSavedData();
}
private async void RetriveUserSavedData()
{
string Result = "";
var path = ApplicationData.Current.LocalFolder.Path + #"\users.db";
var db = new SQLiteAsyncConnection(path);
List<User> allUsers = await db.QueryAsync<User>("Select * From Users");
var count = allUsers.Any() ? allUsers.Count : 0;
foreach (var item in allUsers)
{
Result += "Name: " + item.Name + "\nAge: " + item.Age.ToString() + "\n\n";
}
if (Result.ToString() == "")
{
MessageBox.Show("No Data");
}
else
{
MessageBox.Show(Result.ToString());
}
}
private void txtName_TextChanged(object sender, TextChangedEventArgs e)
{
}
private void txtName_GotFocus(object sender, RoutedEventArgs e)
{
txtName.Text = "";
}
private void txtAge_GotFocus(object sender, RoutedEventArgs e)
{
txtAge.Text = "";
}
}
}
1.-Permanently Insert and Fetch data from database (I had downloaded a code from some website but after running it when I close the emulator and try to view the data previously entered, it won't return it)
When you close the emulator you lost all apps installet on it, so if you close it, you lost all. If you want test your data save, you can close the application (only de app, not the emulator) and open it from your app list in the WP emulator.
Like it should be stored in phone memory or any such place
With SQL lite you can´t store the data in the SD, it will be stored in your app directory, if you want use the SD to store data, you can use binary files
Display the fetched data in listview or grid
To show your data in the listview or grid, you need create a ViewModel or DataContext and then use Binding to "send" the data to de view.

Resources