device: Raspberry PI 3 OS: WIN 10 IOT Programming language: C#
I'm trying to program a 24/7 recorder that will later record everything as soon as the Raspberry is on. The audio file length should be 30 min later. The files will then be stored on an usb-stick in the folders by year, month, day. The folder creation on the usb-stick already works.
The problem I have is that the file is created but has no content. The file is 0kb in size. Here is the code.
Thanks for the help.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Capture;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Windows.Media.MediaProperties;
using Windows.Media.Playback;
using Windows.Storage;
using Windows.Storage.Streams;
namespace Recording_PI
{
/// <summary>
/// Eine leere Seite, die eigenständig verwendet oder zu der innerhalb eines Rahmens navigiert werden kann.
/// </summary>
public sealed partial class MainPage : Page
{
bool isRecording;
LowLagMediaRecording audioRecording;
MediaCapture audioCapture = new MediaCapture();
public MainPage()
{
this.InitializeComponent();
Checked();
Task.Delay(10000).Wait();
Unchecked();
}
private async void Checked()
{
var settings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.Audio;
settings.MediaCategory = Windows.Media.Capture.MediaCategory.Other;
settings.AudioProcessing = Windows.Media.AudioProcessing.Default;
await audioCapture.InitializeAsync(settings);
StorageFolder externalDevices = KnownFolders.RemovableDevices;
IReadOnlyList<StorageFolder> externalDrives = await externalDevices.GetFoldersAsync();
StorageFolder usbStorage = externalDrives[0];
//ENSURE FOLDER EXISTS
if (await usbStorage.TryGetItemAsync("Recording") == null)
await usbStorage.CreateFolderAsync("Recording");
string Folder_Pfad = "Recording\\" + DateTime.Now.Year.ToString();
if (await usbStorage.TryGetItemAsync(Folder_Pfad) == null)
await usbStorage.CreateFolderAsync(Folder_Pfad);
Folder_Pfad = Folder_Pfad + "\\" + DateTime.Now.Month.ToString();
if (await usbStorage.TryGetItemAsync(Folder_Pfad) == null)
await usbStorage.CreateFolderAsync(Folder_Pfad);
Folder_Pfad = Folder_Pfad + "\\" + DateTime.Now.Day.ToString();
if (await usbStorage.TryGetItemAsync(Folder_Pfad) == null)
await usbStorage.CreateFolderAsync(Folder_Pfad);
string Dateiname = "\\" + DateTime.Now.Year.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString() + " "
+ DateTime.Now.Hour.ToString() + "_" + DateTime.Now.Minute.ToString() + "_" + DateTime.Now.Second.ToString()+ ".mp3";
string Dateispeicher_Ort = Folder_Pfad + Dateiname;
StorageFile recordFile = await usbStorage.CreateFileAsync(Dateispeicher_Ort, Windows.Storage.CreationCollisionOption.GenerateUniqueName);
await audioCapture.StartRecordToStorageFileAsync(MediaEncodingProfile.CreateMp3(AudioEncodingQuality.Medium), recordFile);
}
private async void Unchecked()
{
if (isRecording)
{
await audioCapture.StopRecordAsync();
}
}
}
}
The problem I have is that the file is created but has no content. The file is 0kb in size.
This because of your code gets an exception at the below line when running on Raspberry Pi with Windows IoT Core, so the file has not been write content. If you debug the app you will be terminated due to this exception.
await audioCapture.StartRecordToStorageFileAsync(MediaEncodingProfile.CreateMp3(AudioEncodingQuality.Auto), recordFile);
You need to use the following lines instead of the above line:
var audioRecording = await audioCapture.PrepareLowLagRecordToStorageFileAsync(MediaEncodingProfile.CreateM4a(AudioEncodingQuality.Auto), recordFile);
await audioRecording.StartAsync();
Ref: "MediaCapture.PrepareLowLagRecordToStorageFileAsync"
And there are other problems in your code.
isRecording
variable never initiated or assigned any value, so it always false
. So this line could be never executed: await audioCapture.StopRecordAsync();
Unchecked()
method may be executed before Checked()
function complete because in Checked()
method you use await
, so the code will be continue executed, then Task.Delay(10000).Wait();
and Unchecked();
. In this case, the audio will be stopped before started.Another suggestion is adding try-catch in your code so that you can handle exception before the app terminate.
Based on above all I made some edits on your code. Below is the complete code you can try to see if it helps.
MainPage.xaml:
<Page
x:Class="Recording_PI.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Recording_PI"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel VerticalAlignment="Center">
<TextBlock Name="Result" Text="" />
</StackPanel>
</Page>
MainPage.xaml.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Capture;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Windows.Media.MediaProperties;
using Windows.Media.Playback;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.ApplicationModel.Core;
using Windows.UI.Core;
namespace Recording_PI
{
/// <summary>
/// Eine leere Seite, die eigenständig verwendet oder zu der innerhalb eines Rahmens navigiert werden kann.
/// </summary>
public sealed partial class MainPage : Page
{
bool isRecording;
LowLagMediaRecording audioRecording;
MediaCapture audioCapture = new MediaCapture();
public MainPage()
{
this.InitializeComponent();
Checked();
}
private async void Checked()
{
try
{
var settings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.Audio;
settings.MediaCategory = Windows.Media.Capture.MediaCategory.Other;
settings.AudioProcessing = Windows.Media.AudioProcessing.Default;
await audioCapture.InitializeAsync(settings);
StorageFolder externalDevices = KnownFolders.RemovableDevices;
IReadOnlyList<StorageFolder> externalDrives = await externalDevices.GetFoldersAsync();
StorageFolder usbStorage = externalDrives[0];
//ENSURE FOLDER EXISTS
if (await usbStorage.TryGetItemAsync("Recording") == null)
await usbStorage.CreateFolderAsync("Recording");
string Folder_Pfad = "Recording\\" + DateTime.Now.Year.ToString();
if (await usbStorage.TryGetItemAsync(Folder_Pfad) == null)
await usbStorage.CreateFolderAsync(Folder_Pfad);
Folder_Pfad = Folder_Pfad + "\\" + DateTime.Now.Month.ToString();
if (await usbStorage.TryGetItemAsync(Folder_Pfad) == null)
await usbStorage.CreateFolderAsync(Folder_Pfad);
Folder_Pfad = Folder_Pfad + "\\" + DateTime.Now.Day.ToString();
if (await usbStorage.TryGetItemAsync(Folder_Pfad) == null)
await usbStorage.CreateFolderAsync(Folder_Pfad);
string Dateiname = "\\" + DateTime.Now.Year.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString() + " "
+ DateTime.Now.Hour.ToString() + "_" + DateTime.Now.Minute.ToString() + "_" + DateTime.Now.Second.ToString() + ".mp3";
string Dateispeicher_Ort = Folder_Pfad + Dateiname;
StorageFile recordFile = await usbStorage.CreateFileAsync(Dateispeicher_Ort, Windows.Storage.CreationCollisionOption.GenerateUniqueName);
isRecording = true;
//await audioCapture.StartRecordToStorageFileAsync(MediaEncodingProfile.CreateMp3(AudioEncodingQuality.Auto), recordFile);
var audioRecording = await audioCapture.PrepareLowLagRecordToStorageFileAsync(MediaEncodingProfile.CreateM4a(AudioEncodingQuality.Medium), recordFile);
await audioRecording.StartAsync();
Task.Delay(10000).Wait();
Unchecked();
}
catch (Exception ex)
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, ()=> {
Result.Text += ex.Message;
});
}
}
private async void Unchecked()
{
if (isRecording)
{
await audioCapture.StopRecordAsync();
}
}
}
}
Capabilities in package.appxmanifest:
<Capabilities>
<uap:Capability Name="removableStorage" />
<DeviceCapability Name="microphone" />
</Capabilities>