Initial commit — M3U playlist tool with MP3/AAC encoding
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for CreateM3uTest.
|
||||
/// </summary>
|
||||
public class CreateM3uTests
|
||||
{
|
||||
public void CreateM3uTest()
|
||||
{
|
||||
M3uCreate c = new M3uCreate(new DirectoryInfo(@"C:\mp3\"));
|
||||
// c.OutputFilename = @"c:\mym3u.m3u";
|
||||
Debug.WriteLine(c.OutputFilename);
|
||||
c.Create();
|
||||
}
|
||||
|
||||
public void CreateSubM3uTest()
|
||||
{
|
||||
DirectoryInfo rootDir = new DirectoryInfo(@"C:\mp3\");
|
||||
|
||||
int count = 0;
|
||||
foreach (DirectoryInfo subDir in rootDir.GetDirectories())
|
||||
{
|
||||
M3uCreate c = new M3uCreate(subDir);
|
||||
|
||||
Debug.WriteLine(c.OutputFilename);
|
||||
c.Create();
|
||||
|
||||
if (count++ > 10)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// c.OutputFilename = @"c:\mym3u.m3u";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
|
||||
namespace Win32
|
||||
{
|
||||
internal class HiPerfTimer
|
||||
{
|
||||
[DllImport("Kernel32.dll")]
|
||||
private static extern bool QueryPerformanceCounter(
|
||||
out long lpPerformanceCount);
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
private static extern bool QueryPerformanceFrequency(
|
||||
out long lpFrequency);
|
||||
|
||||
private long startTime, stopTime;
|
||||
private long freq;
|
||||
|
||||
// Constructor
|
||||
public HiPerfTimer()
|
||||
{
|
||||
startTime = 0;
|
||||
stopTime = 0;
|
||||
|
||||
if (QueryPerformanceFrequency(out freq) == false)
|
||||
{
|
||||
// high-performance counter not supported
|
||||
throw new Win32Exception();
|
||||
}
|
||||
}
|
||||
|
||||
// Start the timer
|
||||
public void Start()
|
||||
{
|
||||
// lets do the waiting threads there work
|
||||
Thread.Sleep(0);
|
||||
|
||||
QueryPerformanceCounter(out startTime);
|
||||
}
|
||||
|
||||
// Stop the timer
|
||||
public void Stop()
|
||||
{
|
||||
QueryPerformanceCounter(out stopTime);
|
||||
}
|
||||
|
||||
// Returns the duration of the timer (in seconds)
|
||||
public double Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)(stopTime - startTime) / (double)freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class LongestCommonSequenceTests
|
||||
{
|
||||
[Test]
|
||||
public void FunctionalityTest()
|
||||
{
|
||||
//LongestCommonSequence<string> lcs = new LongestCommonSequence<string>();
|
||||
//Debug.WriteLine(new string(lcs.LCS("what do we say", "heya".ToCharArray())));
|
||||
|
||||
List<string> substring = LongestCommonSubstrings.GetLongestSubstring("ABAB", "BABA");
|
||||
Assert.AreEqual(2, substring.Count);
|
||||
Assert.IsTrue(substring.Contains("ABA"));
|
||||
Assert.IsTrue(substring.Contains("BAB"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class Mp3EncoderTests : ProgressCallbackTestBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void StreamingVsOutputMp3EncodingTest()
|
||||
{
|
||||
//String inputWav = "44_16_s.wav";
|
||||
String inputWav = "test1.wav";
|
||||
String outputOptionEncodedMp3 = "outputOptionEncodedMp3.mp3";
|
||||
String streamingEncodedMp3 = "streamingEncodedMp3.mp3";
|
||||
|
||||
Mp3EncodingOptions encOpts = new Mp3EncodingOptions();
|
||||
encOpts.Outfile = "-";
|
||||
encOpts.Infile = "-";
|
||||
|
||||
using (FileStream fs = new FileStream(streamingEncodedMp3, FileMode.OpenOrCreate))
|
||||
{
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts, fs))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(inputWav);
|
||||
}
|
||||
}
|
||||
|
||||
encOpts.Outfile = outputOptionEncodedMp3;
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(inputWav);
|
||||
}
|
||||
|
||||
Mp3FileProperties outputOptionProperties = new Mp3FileProperties(outputOptionEncodedMp3);
|
||||
Mp3FileProperties streamingProperties = new Mp3FileProperties(streamingEncodedMp3);
|
||||
Assert.AreEqual(outputOptionProperties.LengthInSeconds, streamingProperties.LengthInSeconds);
|
||||
|
||||
// FilesAreEqual(outputOptionFileInfo, streamingFileInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void StreamingVsOutputMp3DecodingTest()
|
||||
{
|
||||
String input = "44_16_s.mp3";
|
||||
String outputOptionDecoded = "outputOptionDecoded.wav";
|
||||
String streamingDecoded = "streamingDecode.wav";
|
||||
|
||||
Mp3EncodingOptions encOpts = new Mp3EncodingOptions();
|
||||
encOpts.Outfile = "-";
|
||||
encOpts.Infile = "-";
|
||||
encOpts.Mp3Input = true;
|
||||
encOpts.DecodeWav = true;
|
||||
|
||||
using (FileStream fileStream = new FileStream(streamingDecoded, FileMode.OpenOrCreate))
|
||||
{
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts, fileStream))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(input);
|
||||
}
|
||||
}
|
||||
|
||||
encOpts.Outfile = outputOptionDecoded;
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(input);
|
||||
}
|
||||
|
||||
FileInfo outputOptionFileInfo = new FileInfo(outputOptionDecoded);
|
||||
FileInfo streamingFileInfo = new FileInfo(streamingDecoded);
|
||||
|
||||
FilesAreEqual(outputOptionFileInfo, streamingFileInfo);
|
||||
}
|
||||
|
||||
private void FilesAreEqual(FileInfo file1, FileInfo file2)
|
||||
{
|
||||
//Assert.AreEqual(file1.Length, file2.Length);
|
||||
|
||||
int filePosition = 0;
|
||||
using (FileStream outputOptionFs = file1.OpenRead())
|
||||
using (StreamReader outputOptionSr = new StreamReader(outputOptionFs))
|
||||
using (FileStream streamingFs = file2.OpenRead())
|
||||
using (StreamReader streamingSr = new StreamReader(streamingFs))
|
||||
{
|
||||
char[] outputOptionBuffer = new char[4096];
|
||||
char[] streamingBuffer = new char[4096];
|
||||
|
||||
while (!outputOptionSr.EndOfStream)
|
||||
{
|
||||
int outputOptionReadLength = outputOptionSr.Read(outputOptionBuffer, 0, outputOptionBuffer.Length);
|
||||
int streamingReadLength = streamingSr.Read(streamingBuffer, 0, streamingBuffer.Length);
|
||||
|
||||
Assert.AreEqual(outputOptionReadLength, streamingReadLength);
|
||||
Assert.AreEqual(outputOptionBuffer, streamingBuffer, "offset : " + filePosition);
|
||||
filePosition += outputOptionBuffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests this instance.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void StreamingTest()
|
||||
{
|
||||
String inputWav = "44_16_s.wav";
|
||||
String encodedMp3 = "encodedMp3.mp3";
|
||||
String decodedWav = "decodedWav.wav";
|
||||
String reencodedMp3 = "reencodedMp3.mp3";
|
||||
|
||||
using (FileStream fileStream = new FileStream(encodedMp3, FileMode.OpenOrCreate))
|
||||
{
|
||||
Mp3EncodingOptions encOpts = new Mp3EncodingOptions();
|
||||
encOpts.Outfile = "-";
|
||||
encOpts.Infile = "-";
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts, fileStream))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(inputWav);
|
||||
}
|
||||
}
|
||||
Debug.WriteLine("Finished writing " + encodedMp3);
|
||||
|
||||
Debug.WriteLine("Begin writing " + decodedWav);
|
||||
using (FileStream fileStream = new FileStream(decodedWav, FileMode.OpenOrCreate))
|
||||
{
|
||||
Mp3EncodingOptions wavOpts = new Mp3EncodingOptions();
|
||||
wavOpts.Infile = "-";
|
||||
wavOpts.Outfile = "-";
|
||||
// wavOpts.MonoDownmixing = true;
|
||||
wavOpts.Mp3Input = true;
|
||||
wavOpts.DecodeWav = true;
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(wavOpts, fileStream))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(encodedMp3);
|
||||
}
|
||||
}
|
||||
Debug.WriteLine("Finished writing " + decodedWav);
|
||||
|
||||
using (FileStream fileStream = new FileStream(reencodedMp3, FileMode.OpenOrCreate))
|
||||
{
|
||||
Mp3EncodingOptions encOpts = new Mp3EncodingOptions();
|
||||
encOpts.Outfile = "-";
|
||||
encOpts.Infile = "-";
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp3Encoder(encOpts, fileStream))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput(decodedWav);
|
||||
}
|
||||
}
|
||||
|
||||
Mp3FileProperties reencodedProperties = new Mp3FileProperties(reencodedMp3);
|
||||
Mp3FileProperties encodedProperties = new Mp3FileProperties(encodedMp3);
|
||||
Assert.AreEqual(encodedProperties.FileLength, reencodedProperties.FileLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
public override void StepTo(int val)
|
||||
{
|
||||
if (val % 10 == 0)
|
||||
base.StepTo(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class Mp3EncodingOptionsTests
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Mp3EncodingOptionsTest()
|
||||
{
|
||||
Mp3EncodingOptions e = new Mp3EncodingOptions();
|
||||
e.ChannelMode = ChannelMode.SingleChannel;
|
||||
e.Infile = "-";
|
||||
string arguments = e.GetCommandLineArguments();
|
||||
Debug.WriteLine(arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for MP3HeaderTests.
|
||||
/// </summary>
|
||||
public class Mp3FilePropertiesTests
|
||||
{
|
||||
|
||||
public void Mp3FileDetailsTest()
|
||||
{
|
||||
string[] files = Directory.GetFiles(".", "*.mp3");
|
||||
List<Mp3FileProperties> properties = new List<Mp3FileProperties>();
|
||||
foreach (string mp3Filename in files)
|
||||
{
|
||||
Debug.WriteLine(mp3Filename);
|
||||
Debug.Indent();
|
||||
|
||||
// bool boolIsMP3 = mp3hdr.ReadMP3Information(mp3Filename);
|
||||
Mp3FileProperties fileDetails = new Mp3FileProperties(mp3Filename);
|
||||
properties.Add(fileDetails);
|
||||
if (fileDetails != null)
|
||||
{
|
||||
Debug.WriteLine(GetMp3FilePropertyReport(fileDetails));
|
||||
}
|
||||
Debug.Unindent();
|
||||
}
|
||||
Mp3FileProperties commonProperties = Mp3FileProperties.GetCommonProperties(properties);
|
||||
Debug.WriteLine(GetMp3FilePropertyReport(commonProperties));
|
||||
}
|
||||
|
||||
private static string GetMp3FilePropertyReport(Mp3FileProperties fileDetails)
|
||||
{
|
||||
StringBuilder report = new StringBuilder();
|
||||
report.AppendLine("Filename: " + fileDetails.Mp3PathAndFilename);
|
||||
report.AppendLine("mFileSize: " + fileDetails.FileSize.ToString());
|
||||
report.AppendLine("mBitRate: " + fileDetails.BitRate.ToString());
|
||||
report.AppendLine("mSampleRateIntegerFrequency:" + fileDetails.SampleRateIntegerFrequency.ToString());
|
||||
report.AppendLine("strMode: " + fileDetails.ChannelMode);
|
||||
report.AppendLine("strLengthFo: " + fileDetails.LengthFormatted);
|
||||
report.AppendLine("mLengthInSeconds: " + fileDetails.LengthInSeconds.ToString());
|
||||
|
||||
report.AppendLine("title: " + fileDetails.Id3Title);
|
||||
report.AppendLine("artist: " + fileDetails.Id3Artist);
|
||||
report.AppendLine("album: " + fileDetails.Id3Album);
|
||||
report.AppendLine("track#: " + fileDetails.Id3TrackNumber);
|
||||
report.AppendLine("genre: " + fileDetails.Id3GenreName);
|
||||
return report.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Media;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class Mp4EncoderTests : ProgressCallbackTestBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests Encoding an Mp4 file.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Test()
|
||||
{
|
||||
Mp4EncodingOptions encOpts = new Mp4EncodingOptions();
|
||||
encOpts.OutputFilename = "44_16_s_opts.aac";
|
||||
|
||||
using (ProcessStreamWrapper enc = new Mp4Encoder(encOpts))
|
||||
{
|
||||
enc.ProgressCallback = this;
|
||||
enc.ProcessInput("44_16_s.wav");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
public override void StepTo(int val)
|
||||
{
|
||||
if (val%10 == 0)
|
||||
base.StepTo(val);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class Mp4EncodingOptionsTests
|
||||
{
|
||||
[Test]
|
||||
public void Mp4EncodingOptionsTest()
|
||||
{
|
||||
Mp4EncodingOptions e = new Mp4EncodingOptions();
|
||||
e.RawInputChannels = ChannelMode.SingleChannel;
|
||||
string arguments = e.GetCommandLineArguments();
|
||||
Debug.WriteLine(arguments);
|
||||
|
||||
e = new Mp4EncodingOptions();
|
||||
e.OutputFilename = "har";
|
||||
Debug.WriteLine(e.GetCommandLineArguments());
|
||||
|
||||
e.InputFiles = new string[]{"input.txt"};
|
||||
Debug.WriteLine(e.GetCommandLineArguments());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class ProcessStreamWrapperTests : ProgressCallbackTestBase
|
||||
{
|
||||
private class StdinToStdoutProcess : ProcessStreamWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the process executable filename, such as "LAME.EXE", "FAAC.EXE", etc.
|
||||
/// </summary>
|
||||
/// <value>The process executable filename.</value>
|
||||
protected override string ProcessExecutableFilename
|
||||
{
|
||||
get { return "StdinToStdout.exe"; }
|
||||
}
|
||||
|
||||
public StdinToStdoutProcess(ProcessArguments encOpt, Stream outputStream)
|
||||
: base(encOpt, outputStream)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ProcessStreamWrapperFunctionalityTest()
|
||||
{
|
||||
string inputString = File.ReadAllText("testText.txt");
|
||||
string writtenString = ""; // string that was written to the process
|
||||
|
||||
Stream inputStream = new MemoryStream();
|
||||
|
||||
StreamWriter sw = new StreamWriter(inputStream, Encoding.Default);
|
||||
{
|
||||
int writeSize = 127;
|
||||
for (int i = 0; i < inputString.Length; i += writeSize)
|
||||
{
|
||||
// select a substring of characters from the input string
|
||||
string substring = inputString.Substring(i, (i + writeSize < inputString.Length) ? writeSize : inputString.Length - i);
|
||||
sw.Write(substring.ToCharArray(), 0, substring.Length);
|
||||
writtenString += substring;
|
||||
}
|
||||
}
|
||||
inputStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
Stream outputStream = new MemoryStream();
|
||||
using (StdinToStdoutProcess s = new StdinToStdoutProcess(new ProcessArguments(), outputStream))
|
||||
{
|
||||
s.ProgressCallback = this;
|
||||
s.ProcessInput(inputStream);
|
||||
}
|
||||
|
||||
outputStream.Seek(0, SeekOrigin.Begin);
|
||||
string outputString;
|
||||
using (StreamReader sr = new StreamReader(outputStream, Encoding.Default))
|
||||
{
|
||||
outputString = sr.ReadToEnd();
|
||||
}
|
||||
Assert.AreEqual(writtenString, outputString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the interface progress callback for testing output purposes
|
||||
/// </summary>
|
||||
public class ProgressCallbackTestBase : IProgressCallback
|
||||
{
|
||||
protected string mPreface = "";
|
||||
|
||||
#region IProgressCallback Members
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to initialize
|
||||
/// the progress callback.
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum.</param>
|
||||
/// <param name="maximum">The maximum.</param>
|
||||
public virtual void Begin(int minimum, int maximum)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("Begin min:{0} max:{1}", minimum, maximum));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to initialize
|
||||
/// the progress callback, without setting the range
|
||||
/// </summary>
|
||||
public virtual void Begin()
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("Begin"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to reset the range in the
|
||||
/// progress callback
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum.</param>
|
||||
/// <param name="maximum">The maximum.</param>
|
||||
public virtual void SetRange(int minimum, int maximum)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("SetRange min:{0} max:{1}", minimum, maximum));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to update the progress text.
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
public virtual void SetText(string text)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("SetText : {0}", text));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
/// <param name="val">The val.</param>
|
||||
public virtual void StepTo(int val)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("StepTo : {0}", val));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to step the progress meter to a
|
||||
/// particular value.
|
||||
/// </summary>
|
||||
/// <param name="val">The val.</param>
|
||||
public virtual void Increment(int val)
|
||||
{
|
||||
Debug.WriteLine(mPreface + String.Format("Increment : {0}", val));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this property is true, then you should abort work
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is aborting; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public virtual bool IsAborting
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.WriteLine(mPreface + "IsAborting");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to finalize the progress meter
|
||||
/// </summary>
|
||||
public virtual void End()
|
||||
{
|
||||
Debug.WriteLine(mPreface + "End");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using Utility;
|
||||
|
||||
namespace m3uTool.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TranscodeTest : ProgressCallbackTestBase
|
||||
{
|
||||
static string inputMp3 = "Disc 01 - 04.mp3";
|
||||
string outputAac = inputMp3.Replace(".mp3", ".aac");
|
||||
string outputWav = inputMp3.Replace(".mp3", ".wav");
|
||||
private ReaderProgress mReaderProgress = new ReaderProgress();
|
||||
private WriterProgress mWriterProgress = new WriterProgress();
|
||||
|
||||
private Stream mPipeStream;
|
||||
|
||||
[Test]
|
||||
public void TranscodeSingleThreadTest()
|
||||
{
|
||||
Mp3FileProperties mp3Info = new Mp3FileProperties(inputMp3);
|
||||
Debug.WriteLine(mp3Info);
|
||||
|
||||
mPipeStream = new MemoryStream();
|
||||
|
||||
Mp3ReadThread();
|
||||
if (mPipeStream.CanSeek)
|
||||
mPipeStream.Seek(0, SeekOrigin.Begin);
|
||||
WavWriteThread();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TranscodeMultiThreadTest()
|
||||
{
|
||||
//mPipeStream = new BridgeStream();
|
||||
mPipeStream = new PipeStream();
|
||||
(mPipeStream as PipeStream).BlockLastReadBuffer = true;
|
||||
(mPipeStream as PipeStream).MaxBufferLength = 1 * PipeStream.MB;
|
||||
|
||||
// mPipeStream.MaxBufferLength = 100;
|
||||
|
||||
Thread writeThread = new Thread(new ThreadStart(AacWriteThread));
|
||||
writeThread.Start();
|
||||
|
||||
Thread readThread = new Thread(new ThreadStart(Mp3ReadThread));
|
||||
readThread.Start();
|
||||
|
||||
readThread.Join();
|
||||
(mPipeStream as PipeStream).BlockLastReadBuffer = false;
|
||||
writeThread.Join();
|
||||
}
|
||||
|
||||
|
||||
public void Mp3ReadThread()
|
||||
{
|
||||
//int skip = 3;
|
||||
//int limit = 1;
|
||||
//string directory = @"C:\tmp\venus bak\media\audiobooks\Bret Easton Ellis - Lunar Park";
|
||||
//// string directory = @"C:\tmp\venus bak\media\audiobooks\Clarke, Arthur C. - Space Odyssey 01 - 2001, A Space Odyssey";
|
||||
//// string directory = @"C:\tmp\venus bak\media\audiobooks\Guitar Gym\Part 1 - Alternate Picking (Mp3 And Tab)";
|
||||
//string[] files = Directory.GetFiles(directory);
|
||||
string[] files = new string[]{inputMp3};
|
||||
foreach (string mp3File in files)
|
||||
{
|
||||
//if (skip-- > 0)
|
||||
// continue;
|
||||
//if (limit-- == 0)
|
||||
// break;
|
||||
Debug.WriteLine(mp3File);
|
||||
Mp3FileProperties fp = new Mp3FileProperties(mp3File);
|
||||
Debug.WriteLine(fp.ToString());
|
||||
// Mp3 to wav
|
||||
using (FileStream fileStream = new FileStream(mp3File, FileMode.Open))
|
||||
{
|
||||
Mp3EncodingOptions opts = new Mp3EncodingOptions();
|
||||
opts.Infile = "-";
|
||||
opts.Outfile = "-";
|
||||
// opts.BitRate = BitRate.KBPS_32;
|
||||
// opts.Freeformat = true;
|
||||
opts.Mp3Input = true;
|
||||
opts.DecodeWav = true;
|
||||
// opts.DisableWavHeader = true;
|
||||
Debug.WriteLine("MP3 : " + opts.GetCommandLineArguments());
|
||||
// opts.Freeformat = true;
|
||||
// read from the sr, and write to the memory stream
|
||||
using (Mp3Encoder encoder = new Mp3Encoder(opts, mPipeStream))
|
||||
{
|
||||
encoder.ProgressCallback = mReaderProgress;
|
||||
encoder.ProcessInput(fileStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WavWriteThread()
|
||||
{
|
||||
using (FileStream fs = new FileStream(outputWav, FileMode.OpenOrCreate))
|
||||
using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))
|
||||
using (StreamReader sr = new StreamReader(mPipeStream, Encoding.Default))
|
||||
{
|
||||
char[] buffer = new char[1024 * 1024];
|
||||
|
||||
while (!sr.EndOfStream)
|
||||
{
|
||||
int readCount = sr.Read(buffer, 0, buffer.Length);
|
||||
sw.Write(buffer, 0, readCount);
|
||||
mWriterProgress.SetText("Wrote " + buffer.Length);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void AacWriteThread()
|
||||
{
|
||||
Mp4EncodingOptions mp4Opts = new Mp4EncodingOptions();
|
||||
mp4Opts.OutputFilename = outputAac;
|
||||
mp4Opts.RawPCMSwapInputBytes = true;
|
||||
mp4Opts.RawPCMInputMode = true;
|
||||
mp4Opts.RawPCMInputSampleRate = 16;
|
||||
mp4Opts.RawPCMInputSampleSize = SampleRateFrequency.Hz_44100;
|
||||
mp4Opts.RawInputChannels = ChannelMode.Stereo;
|
||||
Debug.WriteLine("AAC : " + mp4Opts.GetCommandLineArguments());
|
||||
|
||||
using (Mp4Encoder encoder = new Mp4Encoder(mp4Opts))
|
||||
{
|
||||
encoder.ProgressCallback = mWriterProgress;
|
||||
encoder.ProcessInput(mPipeStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ReaderProgress : ProgressCallbackTestBase
|
||||
{
|
||||
public ReaderProgress()
|
||||
{
|
||||
mPreface = "Reader: ";
|
||||
}
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
public override void StepTo(int val)
|
||||
{
|
||||
if (val % 10 == 0)
|
||||
{
|
||||
|
||||
base.StepTo(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class WriterProgress : ProgressCallbackTestBase
|
||||
{
|
||||
public WriterProgress()
|
||||
{
|
||||
|
||||
mPreface = "\t\t\t\tWriter: ";
|
||||
}
|
||||
/// <summary>
|
||||
/// Call this method from the worker thread to increase the progress
|
||||
/// counter by a specified value.
|
||||
/// </summary>
|
||||
public override void StepTo(int val)
|
||||
{
|
||||
if (val % 10 == 0)
|
||||
{
|
||||
|
||||
base.StepTo(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user