Skip to content

Commit

Permalink
Output file to spytify to only transcode to mp3 at the end of the rec…
Browse files Browse the repository at this point in the history
…ording

now able to record proper mp3 on power saver mode - close issue #92
related issue #102
  • Loading branch information
jwallet committed Jan 7, 2020
1 parent 30928b1 commit 6699a0c
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 74 deletions.
19 changes: 13 additions & 6 deletions EspionSpotify/MediaTags/MP3Tags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@ public async Task SaveMediaTags()
{
var mp3 = TagLib.File.Create(CurrentFile);

if (OrderNumberInMediaTagEnabled && Count.HasValue)
{
mp3.Tag.Track = (uint)Count.Value;
}
else if (Track.AlbumPosition != null)
var trackNumber = GetTrackNumber();
if (trackNumber.HasValue)
{
mp3.Tag.Track = (uint)Track.AlbumPosition;
mp3.Tag.Track = (uint)trackNumber.Value;
}

mp3.Tag.Title = Track.Title;
Expand Down Expand Up @@ -64,6 +61,16 @@ public async Task SaveMediaTags()
mp3.Dispose();
}

private int? GetTrackNumber()
{
if (OrderNumberInMediaTagEnabled && Count.HasValue)
{
return Count.Value;
}

return Track.AlbumPosition;
}

private TagLib.Picture GetAlbumCoverToPicture(byte[] data)
{
if (data == null) return new TagLib.Picture();
Expand Down
52 changes: 52 additions & 0 deletions EspionSpotify/Models/OutputFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EspionSpotify.Models
{
public class OutputFile
{
private const string SPYTIFY = "spytify";
private const int FIRST_SONG_NAME_COUNT = 1;


public string Path { get; set; }
public string File { get; set; }
public int Count { get; private set; }
public string Separator { get; set; }
public string Extension { get; set; }

public OutputFile()
{
Count = FIRST_SONG_NAME_COUNT;
}

public void Increment()
{
Count++;
}

public override string ToString()
{

return $@"{Path}\{File}{GetAddedCount()}.{Extension}";
}

public string ToPendingFileString()
{
return $@"{Path}\{File}{GetAddedCount()}.{SPYTIFY}";
}

public string ToTranscodingToMP3String()
{
return $@"{Path}\{File}{GetAddedCount()}.{Extension}.{SPYTIFY}";
}

private string GetAddedCount()
{
return Count > FIRST_SONG_NAME_COUNT ? $"{Separator}{Count}" : "";
}
}
}
172 changes: 104 additions & 68 deletions EspionSpotify/Recorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@

namespace EspionSpotify
{
internal class Recorder: IRecorder
internal class Recorder : IRecorder
{
public int CountSeconds { get; set; }
public bool Running { get; set; }

private readonly UserSettings _userSettings;
private readonly Track _track;
private readonly IFrmEspionSpotify _form;
private string _currentFile;
private string _currentFilePending;
private OutputFile _currentOutputFile;
private WasapiLoopbackCapture _waveIn;
private Stream _writer;
private readonly FileManager _fileManager;
Expand All @@ -44,10 +43,9 @@ public async void Run()
_waveIn.DataAvailable += WaveIn_DataAvailable;
_waveIn.RecordingStopped += WaveIn_RecordingStopped;

_currentFile = _fileManager.BuildFileName(_userSettings.OutputPath);
_currentFilePending = _fileManager.BuildSpytifyFileName(_currentFile);
_currentOutputFile = _fileManager.GetOutputFile(_userSettings.OutputPath);

_writer = GetFileWriter(_currentFilePending, _waveIn, _userSettings);
_writer = new WaveFileWriter(_currentOutputFile.ToPendingFileString(), _waveIn.WaveFormat);

if (_writer == null)
{
Expand All @@ -56,7 +54,7 @@ public async void Run()
}

_waveIn.StartRecording();
_form.WriteIntoConsole("logRecording", _fileManager.GetFileName(_currentFile));
_form.WriteIntoConsole("logRecording", _currentOutputFile.File);

while (Running)
{
Expand All @@ -66,107 +64,145 @@ public async void Run()
_waveIn.StopRecording();
}

private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
private async void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
{
// TODO: add buffer handler from argument
_writer.Write(e.Buffer, 0, e.BytesRecorded);
if (_writer != null) await _writer.WriteAsync(e.Buffer, 0, e.BytesRecorded);
}

private void WaveIn_RecordingStopped(object sender, StoppedEventArgs e)
private async void WaveIn_RecordingStopped(object sender, StoppedEventArgs e)
{
if (_writer != null)
{
_writer.Flush();
_waveIn.Dispose();
await _writer.FlushAsync();
_writer.Dispose();
_waveIn.Dispose();
}

if (CountSeconds < _userSettings.MinimumRecordedLengthSeconds)
{
_form.WriteIntoConsole("logDeleting", _fileManager.GetFileName(_currentFile), _userSettings.MinimumRecordedLengthSeconds);
_fileManager.DeleteFile(_currentFilePending);
_form.WriteIntoConsole("logDeleting", _currentOutputFile.File, _userSettings.MinimumRecordedLengthSeconds);
_fileManager.DeleteFile(_currentOutputFile.ToPendingFileString());
return;
}

var length = TimeSpan.FromSeconds(CountSeconds).ToString(@"mm\:ss");
_form.WriteIntoConsole("logRecorded", _track.ToString(), length);

_fileManager.Rename(_currentFilePending, _currentFile);

if (!_userSettings.MediaFormat.Equals(MediaFormat.Mp3)) return;

var mp3TagsInfo = new MediaTags.MP3Tags()
{
Track = _track,
OrderNumberInMediaTagEnabled = _userSettings.OrderNumberInMediaTagEnabled,
Count = _userSettings.OrderNumber,
CurrentFile = _currentFile
};

Task.Run(async () => await mp3TagsInfo.SaveMediaTags());
await UpdateOutputFileBasedOnMediaFormat();
}

private Stream GetFileWriter(string file, WasapiLoopbackCapture waveIn, UserSettings settings)
private Stream GetFileWriter(string file, WaveFormat waveFormat, UserSettings settings)
{
if (settings.MediaFormat.Equals(MediaFormat.Mp3))
switch (settings.MediaFormat)
{
try
{
return new LameMP3FileWriter(file, waveIn.WaveFormat, settings.Bitrate);
}
catch (ArgumentException ex)
{
var resource = "logUnknownException";
var args = ex.Message;

if (!Directory.Exists(settings.OutputPath))
{
resource = "logInvalidOutput";
}
else if (ex.Message.StartsWith("Unsupported Sample Rate"))
case MediaFormat.Mp3:
try
{
resource = "logUnsupportedRate";
return new LameMP3FileWriter(file, waveFormat, settings.Bitrate);
}
else if (ex.Message.StartsWith("Access to the path"))
catch (ArgumentException ex)
{
resource = "logNoAccessOutput";
LogLameMP3FileWriterArgumentException(ex, settings.OutputPath);
return null;
}
else if (ex.Message.StartsWith("Unsupported number of channels"))
catch (Exception ex)
{
var numberOfChannels = ex.Message.Length > 32 ? ex.Message.Remove(0, 31) : "?";
var indexOfBreakLine = numberOfChannels.IndexOf("\r\n");
numberOfChannels = numberOfChannels.Substring(0, indexOfBreakLine != -1 ? indexOfBreakLine : 0);
resource = "logUnsupportedNumberChannels";
args = numberOfChannels;
LogLameMP3FileWriterException(ex);
return null;
}

_form.WriteIntoConsole(resource, args);
return null;
}
catch (Exception ex)
{
if (ex.Message.Contains("Unable to load DLL"))
case MediaFormat.Wav:
try
{
_form.WriteIntoConsole("logMissingDlls");
return new WaveFileWriter(file, waveFormat);
}
else
catch (Exception ex)
{
_form.WriteIntoConsole("logUnknownException", ex.Message);
Console.WriteLine(ex.Message);
return null;
}
Console.WriteLine(ex.Message);
default:
return null;
}
}
}

private async Task UpdateOutputFileBasedOnMediaFormat()
{
switch (_userSettings.MediaFormat)
{
case MediaFormat.Wav:
_fileManager.Rename(_currentOutputFile.ToPendingFileString(), _currentOutputFile.ToString());
return;
case MediaFormat.Mp3:
using (var reader = new WaveFileReader(_currentOutputFile.ToPendingFileString()))
{
using (var writer = GetFileWriter(_currentOutputFile.ToTranscodingToMP3String(), _waveIn.WaveFormat, _userSettings))
{
await reader.CopyToAsync(writer);
await writer.FlushAsync();
}
}

_fileManager.DeleteFile(_currentOutputFile.ToPendingFileString());
_fileManager.Rename(_currentOutputFile.ToTranscodingToMP3String(), _currentOutputFile.ToString());

var mp3TagsInfo = new MediaTags.MP3Tags()
{
Track = _track,
OrderNumberInMediaTagEnabled = _userSettings.OrderNumberInMediaTagEnabled,
Count = _userSettings.OrderNumber,
CurrentFile = _currentOutputFile.ToString()
};
await mp3TagsInfo.SaveMediaTags();

return;
default:
return;
}
}

private void LogLameMP3FileWriterArgumentException(ArgumentException ex, string outputPath)
{
var resource = "logUnknownException";
var args = ex.Message;

if (!Directory.Exists(outputPath))
{
resource = "logInvalidOutput";
}
else if (ex.Message.StartsWith("Unsupported Sample Rate"))
{
resource = "logUnsupportedRate";
}
else if (ex.Message.StartsWith("Access to the path"))
{
resource = "logNoAccessOutput";
}
else if (ex.Message.StartsWith("Unsupported number of channels"))
{
var numberOfChannels = ex.Message.Length > 32 ? ex.Message.Remove(0, 31) : "?";
var indexOfBreakLine = numberOfChannels.IndexOf("\r\n");
numberOfChannels = numberOfChannels.Substring(0, indexOfBreakLine != -1 ? indexOfBreakLine : 0);
resource = "logUnsupportedNumberChannels";
args = numberOfChannels;
}

try
_form.WriteIntoConsole(resource, args);
}

private void LogLameMP3FileWriterException(Exception ex)
{
if (ex.Message.Contains("Unable to load DLL"))
{
return new WaveFileWriter(file, waveIn.WaveFormat);
_form.WriteIntoConsole("logMissingDlls");
}
catch (Exception ex)
else
{
Console.WriteLine(ex.Message);
return null;
_form.WriteIntoConsole("logUnknownException", ex.Message);
}

Console.WriteLine(ex.Message);
}
}
}

0 comments on commit 6699a0c

Please sign in to comment.