Add simple support for PCM audio source wrapping

Former-commit-id: d8810682ef
This commit is contained in:
Julien Loir 2021-04-12 13:50:27 +02:00
parent 7bee36e2ca
commit 32dfb34724
3 changed files with 88 additions and 0 deletions

View file

@ -0,0 +1,27 @@
using FFMpegCore.Pipes;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
public class PcmAudioSampleWrapper : IAudioSample
{
//This could actually be short or int, but copies would be inefficient.
//Handling bytes lets the user decide on the conversion, and abstract the library
//from handling shorts, unsigned shorts, integers, unsigned integers and floats.
private readonly byte[] _sample;
public PcmAudioSampleWrapper(byte[] sample)
{
_sample = sample;
}
public void Serialize(Stream stream)
{
stream.Write(_sample, 0, _sample.Length);
}
public async Task SerializeAsync(Stream stream, CancellationToken token)
{
await stream.WriteAsync(_sample, 0, _sample.Length, token);
}
}

View file

@ -0,0 +1,16 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace FFMpegCore.Pipes
{
/// <summary>
/// Interface for Audio sample
/// </summary>
public interface IAudioSample
{
void Serialize(Stream stream);
Task SerializeAsync(Stream stream, CancellationToken token);
}
}

View file

@ -0,0 +1,45 @@
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace FFMpegCore.Pipes
{
/// <summary>
/// Implementation of <see cref="IPipeSource"/> for a raw audio stream that is gathered from <see cref="IEnumerator{IAudioFrame}"/>
/// </summary>
public class RawAudioPipeSource : IPipeSource
{
private readonly IEnumerator<IAudioSample> _sampleEnumerator;
public string Format { get; set; } = "s16le";
public uint SampleRate { get; set; } = 8000;
public uint Channels { get; set; } = 1;
public RawAudioPipeSource(IEnumerator<IAudioSample> sampleEnumerator)
{
_sampleEnumerator = sampleEnumerator;
}
public RawAudioPipeSource(IEnumerable<IAudioSample> sampleEnumerator)
: this(sampleEnumerator.GetEnumerator()) { }
public string GetStreamArguments()
{
return $"-f {Format} -ar {SampleRate} -ac {Channels}";
}
public async Task WriteAsync(Stream outputStream, CancellationToken cancellationToken)
{
if (_sampleEnumerator.Current != null)
{
await _sampleEnumerator.Current.SerializeAsync(outputStream, cancellationToken).ConfigureAwait(false);
}
while (_sampleEnumerator.MoveNext())
{
await _sampleEnumerator.Current!.SerializeAsync(outputStream, cancellationToken).ConfigureAwait(false);
}
}
}
}