首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >火猴将mp3流转换为十六进制和反转

火猴将mp3流转换为十六进制和反转
EN

Stack Overflow用户
提问于 2018-12-07 00:35:27
回答 1查看 655关注 0票数 0

我尝试将移动麦克风中的音频保存到Tmemorystream中,然后使用此函数将其转换为十六进制:

代码语言:javascript
复制
function StreamToHexStr(AStream: TStream): string;
const
 HexArr: array[0..15] of char =
 ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
var
 AByte: Byte;
 i: Integer;
begin
 SetLength(Result, AStream.Size * 2);
 AStream.Position := 0;
 for i := 0 to AStream.Size - 1 do
 begin
   AStream.ReadBuffer(AByte, SizeOf(AByte));
   Result[i * 2 + 1] := HexArr[AByte shr 4];
   Result[i * 2 + 2] := HexArr[AByte and $0F];
 end;
end;

输出为十六进制字符串

在将其传输到第二个设备后,我必须将十六进制代码更改为Tmemorystream,并使用以下函数播放它:

代码语言:javascript
复制
Stream := TMemoryStream.Create;
try
  Writer := TBinaryWriter.Create(Stream);
  try
    Writer.Write(TEncoding.UTF8.GetBytes(ReciavedSTR));
  finally
    Writer.Free;
  end;
  Stream.SaveToFile( TPath.GetSharedMoviesPath()+'/record2.mp3' );

但是record2.mp3是不可播放的,它只包含转换后的十六进制字符串

我的代码出了什么问题?

当我用下面的代码将录制的流保存到一个文件中时,这是一个简单的测试

代码语言:javascript
复制
FOutputStream.SaveToFile( TPath.GetSharedMoviesPath()+'/record.mp3' );

它工作得很好。

更新项目概念:

硬件发送器通过串口从手机获取406个十六进制字符,并将其传输到第二个设备,然后接收器将十六进制字符串传送到第二个手机,第二个手机必须将这些字符串连接起来,并将其转换为可听得见的声音。

base64到流和流保存到文件的样例输出

sample mp3 file

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-07 04:43:58

首先,让我回答你最初的问题。

如何将流转换为base16 (也称为ASCII十六进制)。

您要转换为base16的代码是正确的,以下是一个基本相同的版本:

代码语言:javascript
复制
function StreamToHexStr(const AStream: TStream): String;
const
  cMap : array[0..15] of Char = (
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
    'A', 'B', 'C', 'D', 'E', 'F');
var
  lData: Byte;
  lPos: Integer;
begin
  Setlength(Result, AStream.Size * 2);
  AStream.Position := 0; 
  lPos := Low(Result);
  while AStream.ReadData(lData) = sizeof(lData) do begin
    Result[lPos]     := cMap[lData shr 4];
    Result[lPos + 1] := cMap[lData and $0F];
    Inc(lPos, 2);
  end;
end;

要将字符串转换回流,请尝试执行以下操作:

代码语言:javascript
复制
procedure HexStrToStream(const AString: String; AStream: TStream);
const
  // Mapping vom ASCII-Code to value
  cMap: array['0'..'F'] of Byte  = (
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,  // $30..$39 / '0'..'9'
    100, 100, 100, 100, 100, 100, 100, //  $3A..$40
    10, 11, 12, 13, 14, 15); // $41..$46 / 'A'..'F'
var
  lPos: Integer;
begin
  lPos := Low(AString);
  while lPos < High(AString) do begin
    AStream.WriteData(UInt8(cMap[AString[lPos]] shl 4 + cMap[AString[lPos + 1]]));
    Inc(lPos, 2);
  end;
end;

要使用此代码,只需执行以下操作:

代码语言:javascript
复制
Base16String := StreamToHexStr(MP3Stream);

在发送方和接收方执行以下操作:

代码语言:javascript
复制
lRecvStream := TMemoryStream.Create();
try
  HexStrToStream(Base16RecvString, RecvStream);
  lRecvStream.SaveToFile('Record.mp3');
finally
  lRecvStream.Free();
end;

如何对base64执行相同的操作

在发送端使用TMemoryStream时,您只需执行以下操作:

代码语言:javascript
复制
lString := TNetEncoding.Base64.EncodeBytesToString(lInStream.Memory, lInStream.Size);

在接收端,您使用TBytesStream (它是TMemoryStream的后代):

代码语言:javascript
复制
lRecvStream := TBytesStream.Create(TNetEncoding.Base64.DecodeStringToBytes(lString));
try
  lRecvStream.SaveToFile('Record.mp3');
finally
  lRecvStream.Free();
end;

你可能会考虑的事情

在数据传输过程中,某些字节可能会更改或丢失。有时不会接收到整个数据包。根据您的要求,您的应用程序可能需要一些保护以防止此类错误。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53655841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档