音声であるストリームを受信して再生したい。そのため、ソケットを構成し、受信は正常に機能しますが、ストリームを正しく再生するのに問題があります。着信ストリームが正常であることを完全に確信しています。Android と iOS でテスト済み。
受信ストリーム
private async void SocketOnMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
var result = args.GetDataStream();
var resultStream = result.AsStreamForRead(4096);
using (var reader = new StreamReader(resultStream))
{
var audio = await reader.ReadToEndAsync();
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
Debug.WriteLine("audio.length "+audio.Length);
AudioSteam.AddBytes(audio);
});
}
}
サウンドを再生するために、このチュートリアルから少しコードを変更します
私の変更されたコード
protected override void GetSampleAsync(MediaStreamType mediaStreamType)
{
// Send out the sample
ReportGetSampleCompleted(new MediaStreamSample(mediaStreamDescription,
memoryStream,
0,
BufferSize,
timestamp,
mediaSampleAttributes));
// Prepare for next sample
timestamp += BufferSamples * 10000000L / sampleRate;
}
そして、ストリームを提供するためのメソッドを1つ追加します
public void AddBytes(string bytes) {
var audioBytes = System.Text.Encoding.UTF8.GetBytes(bytes);
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.Write(audioBytes,0,audioBytes.Length);
}
どうしたの?受けたり、弾いたりして、どこを間違えますか?
更新: UI スレッドは連続音を読み取るための最良の方法ではないようです。だから私はそれを取り除きました、そして今受信方法はこのようになります
private void SocketOnMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
var result = args.GetDataStream();
var resultStream = result.AsStreamForRead(4096);
var reader = new StreamReader(resultStream);
var audio = reader.ReadToEnd();
AudioSteam.AddBytes(audio);
}
さらに、MediaSourceStream の設定が悪い可能性があります。ATMはこのように設定されています
const int ChannelCount = 1;
const int BitsPerSample = 2;
const int BufferSamples = 16;
const int BufferSize = 4096; //same as max buffer for iOS and Android
protected override void OpenMediaAsync()
{
int byteRate = sampleRate * ChannelCount * BitsPerSample / 8;
Debug.WriteLine("ByteRate: "+byteRate);
short blockAlign = (short)(ChannelCount * (BitsPerSample / 8));
//Build string-based wave-format structure
string waveFormat = "";
waveFormat += ToLittleEndianString(string.Format("{0:X4}", 1)); // indicates PCM
waveFormat += ToLittleEndianString(string.Format("{0:X4}", ChannelCount));
waveFormat += ToLittleEndianString(string.Format("{0:X8}", sampleRate));
waveFormat += ToLittleEndianString(string.Format("{0:X8}", byteRate));
waveFormat += ToLittleEndianString(string.Format("{0:X4}", blockAlign));
waveFormat += ToLittleEndianString(string.Format("{0:X4}", BitsPerSample));
waveFormat += ToLittleEndianString(string.Format("{0:X4}", 0));
// Put wave format string in media streams dictionary
var mediaStreamAttributes = new Dictionary<MediaStreamAttributeKeys, string>();
mediaStreamAttributes[MediaStreamAttributeKeys.CodecPrivateData] = waveFormat;
// Make description to add to available streams list
var availableMediaStreams = new List<MediaStreamDescription>();
mediaStreamDescription = new MediaStreamDescription(MediaStreamType.Audio, mediaStreamAttributes);
availableMediaStreams.Add(mediaStreamDescription);
// Set some appropriate keys in the media source dictionary
var mediaSourceAttributes = new Dictionary<MediaSourceAttributesKeys, string>();
mediaSourceAttributes[MediaSourceAttributesKeys.Duration] = "0";
mediaSourceAttributes[MediaSourceAttributesKeys.CanSeek] = "false";
// Signal that the open operation is completed
ReportOpenMediaCompleted(mediaSourceAttributes, availableMediaStreams);
}
このように設定されているiOS/Androidと同様に設定しようとしていました
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100.00;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 2;
audioFormat.mBytesPerFrame = 2;
そのアップデートがいくつかの光を当てることを願っています。