好久没写BLOG了,送上一份原创的DELPHI版MP3切割,splitMp3为切割函数,支持按时间切割和按大小切割。望大家支持。

参考VC的资料编写的MP3切割DELPHI版单元.

unit UnitMp3DataUtil;

{

MP3 Cut Unit.

@author Jim Wu

2009-08

}

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls;

type

Mp3SplitMode = (Mp3SplitByTime, Mp3SplitByDateLength);

TMp3DataInfo = packed record

isMp3: Boolean;

bitrate: Integer;

sampleRate: Integer;

isMono: Boolean;

isVBR: Boolean;

end;

function readMp3Head(fileName: string): TMp3DataInfo;

function splitMp3(mode: Mp3SplitMode; length: Integer; fr: TFileStream; writeFileName: string; var actualLength: Integer; var actualMillisecond: Integer): integer;

const

mpegBitrateTable: array[1..2,1..3,1..14] of Integer=(

(

( 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448),

( 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384),

( 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320)

),

(

( 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256),

(  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160),

(  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160)

)

);

samplingRateTable: array[1..3,0..2] of Integer=(

(44100,48000,32000),

(22050,24000,16000),

(11025,12000,8000)

);

frameLengthTable: array[1..2,1..3] of Integer=(

(48000,144000,144000),

(24000, 72000, 72000)

);

samplesPerFrameTable: array[1..2,1..3] of Integer=(

( 384,1152,1152),

( 384,1152, 576)

);

implementation

function readMp3Head(fileName: string): TMp3DataInfo;

var

binData: array [0..3] of Byte;

tempDate: array [0..3] of Byte;

fr: TFileStream;

mpegPadding: Byte;

mpegVersion: Double;

mpegLayer: Byte;

seekDataLength: Integer;

begin

fr := TFileStream.Create(fileName, fmOpenRead);

fr.Read(binData, 4);

if (binData[0] = $49) and (binData[1] = $44) and (binData[2] = $33) then

begin //readMp3Head

fr.Seek(2, soFromCurrent);

fr.Read(tempDate, 4); //解析长度

seekDataLength := tempDate[0] and $7F shl 21 + tempDate[1] and $7F shl 14 + tempDate[2] and $7F shl 7 + tempDate[3] and $7F;

fr.Seek(seekDataLength, soFromCurrent);

fr.Read(binData, 4);

end;

if binData[0] = $FF then //DATA Frame

begin

case binData[1] shr 3 and $3 of

0: mpegVersion := 2.5;

1: ; //reserved

2: mpegVersion := 2;

3: mpegVersion := 1;

end;

mpegLayer := 4 - (binData[1] shr 1 and $3);

result.bitrate := mpegBitrateTable[Trunc(mpegVersion)][mpegLayer][binData[2] shr 4 and $F];

result.sampleRate := samplingRateTable[Trunc(mpegVersion+0.5)][binData[2] shr 2 and $3];

mpegPadding := binData[2] shr 1 and $1;

if binData[3] shr 6 and $3 = 3 then

result.isMono := True

else

Result.isMono := False;

fr.Seek(32, soFromCurrent); //read Xing(VBR) Flag

fr.Read(tempDate, 4);

if (tempDate[0] = $58) and (tempDate[1] = $69) and (tempDate[2] = $6E) and (tempDate[3] = $67) then

Result.isVBR := True

else

Result.isVBR := False;

Result.isMp3 := True;

end

else

Result.isMp3 := False; //not MP3 file

fr.Free;

end;

function processFrame(fr: TFileStream; fw: TFileStream; var writeLength: Integer; var writeMillisecond: double): LongInt; //返回:文件位置

var

binData: array [0..3] of Byte;

seekDataLength: Integer;

mpegPadding: Byte;

mpegVersion: Double;

mpegLayer: Byte;

mpegBitrate: Integer;

mpegSamplingRate : Integer;

trackMode: Integer;

begin

fr.Read(binData, 4);

if (binData[0] = $49) and (binData[1] = $44) and (binData[2] = $33) then

begin //IDV3

fr.Seek(2, soFromCurrent);

fr.Read(binData, 4); //解析长度

seekDataLength := binData[0] and $7F shl 21 + binData[1] and $7F shl 14 + binData[2] and $7F shl 7 + binData[3] and $7F;

fr.Seek(seekDataLength, soFromCurrent); //instead of write

writeLength := 0;

writeMillisecond := 0;

end

else

if binData[0] = $FF then //DATA Frame

begin

case binData[1] shr 3 and $3 of

0: mpegVersion := 2.5;

1: ; //reserved

2: mpegVersion := 2;

3: mpegVersion := 1;

end;

mpegLayer := 4 - (binData[1] shr 1 and $3);

mpegBitrate := mpegBitrateTable[Trunc(mpegVersion)][mpegLayer][binData[2] shr 4 and $F];

mpegSamplingRate  := samplingRateTable[Trunc(mpegVersion+0.5)][binData[2] shr 2 and $3];

mpegPadding := binData[2] shr 1 and $1;

seekDataLength := Trunc((samplesPerFrameTable[Trunc(mpegVersion)][mpegLayer] / 8 * mpegBitrate * 1000) / mpegSamplingRate) + mpegPadding;

fr.Seek(32, soFromCurrent); //read Xing(VBR) Flag

fr.Read(binData, 4);

if (binData[0] = $58) and (binData[1] = $69) and (binData[2] = $6E) and (binData[3] = $67) then

begin

fr.Seek(seekDataLength - 4 - 32 - 4, soFromCurrent);

result := fr.Position;

writeLength := 0;

writeMillisecond := 0;

end

else //writeData

begin

fr.Seek(-32 - 4 - 4, soFromCurrent);

fw.CopyFrom(fr, seekDataLength); //copy a frame

writeLength := seekDataLength;

writeMillisecond := samplesPerFrameTable[Trunc(mpegVersion)][mpegLayer] * 1000.0 / mpegSamplingRate;

result := fr.Position;

end;

end

else

begin

writeLength := 0;

writeMillisecond := 0;

result := fr.Position;

end;

end;

function splitMp3(mode: Mp3SplitMode; length: Integer; fr: TFileStream; writeFileName: string; var actualLength: Integer; var actualMillisecond: Integer): integer;

//length:限制,对于SplitByTime,为毫秒,对于长度,为byte

//actualLength为实际切分长度,actualTime为实际切分毫秒

var

writeLength: Integer;

writeMillisecond: double;

tempMillisecond: double;

fw: TFileStream;

total: double;

begin

fw := TFileStream.Create(writeFileName, fmOpenWrite or fmCreate);

total := 0;

actualLength := 0;

tempMillisecond := 0;

while True do

begin

if fr.Position >= fr.Size - 4 then

break;

if total >= length then

break;

result := processFrame(fr, fw, writeLength, writeMillisecond);

Inc(actualLength, writeLength);

tempMillisecond := tempMillisecond + writeMillisecond;

if mode = Mp3SplitByTime then

total := total + writeMillisecond

else

total := total + writeLength;

end;

actualMillisecond := Trunc(tempMillisecond);

fw.Free;

end;

end.

delphi 裁剪mp3_delphi版MP3切割 | 学步园相关推荐

  1. delphi 裁剪mp3_delphi版MP3切割

    好久没写BLOG了,送上一份原创的DELPHI版MP3切割,splitMp3为切割函数,支持按时间切割和按大小切割.望大家支持. 参考VC的资料编写的MP3切割DELPHI版单元. unit Unit ...

  2. delphi版MP3切割

    好久没写BLOG了,送上一份原创的DELPHI版MP3切割,splitMp3为切割函数,支持按时间切割和按大小切割.望大家支持. 参考VC的资料编写的MP3切割DELPHI版单元. unit Unit ...

  3. apache arm 交叉编译_移植apache2 ARM版 – 交叉编译apache2 | 学步园

    下载apache2 http://apache.fayea.com/apache-mirror//httpd/httpd-2.4.6.tar.bz2 1. tar jxvf httpd-2.4.6.t ...

  4. delphi 裁剪mp3_MP3剪切器下载-MP3剪切器正式版下载[电脑版]-PC下载网

    MP3剪切器正式版 MP3剪切器正式版是款针对MP3音频所打造的剪切工具.MP3剪切器相当拥有了MP3剪切器,WMA剪切器,WAV剪切器,AMR剪切器等,非常适合做铃声制作软件.MP3剪切器还支持MP ...

  5. layui上传图片列表展示_layui怎么做图片在列表中显示 | 学步园

    layui table中显示图片的方法: 图片需要用到模板.templet: 注意div不可省略,48px指的是div的高度,如果要决定img图片的高度,需要单独设计style ',style:'he ...

  6. java调用存储过程sqlserver_Java调用SqlServer存储过程怎么实现 | 学步园

    在使用Java开发时,经常会遇到调用SqlServer存储过程的问题.下面学步园小编来讲解下Java调用SqlServer存储过程怎么实现? Java调用SqlServer存储过程怎么实现 1.数据库 ...

  7. mysql 异常关机后 无法查数据_MySQL数据库非法关机造成数据表损坏怎么排查 | 学步园...

    该篇文章我们介绍由于非法硬件关机,造成了MySQL数据库的数据表损坏,数据库不能正常运行的一个实例.下面学步园小编来讲解下MySQL数据库非法关机造成数据表损坏怎么排查? MySQL数据库非法关机造成 ...

  8. mysql超长sql查询_超长SQL怎么查询?MySQL列长度限制有哪些 | 学步园

    MySQL字符串的限制长度看似重要性不要,其实和整个MySQL数据库的安全性是息息相关的,很值得我们去深入研究分析.SQL注入攻击一直都在被广泛的讨论,然而人们却忽略了今天我将要介绍的这两个安全隐患, ...

  9. netmiko 记录日志_Pythonnetmiko模块的使用 | 学步园

    一.简介 此模块用于简化paramiko与网络设备之间的ssh连接,可在windows与Unix平台使用 二.目前支持的设备 (2019.03.07) Regularly tested Arista ...

最新文章

  1. 洛谷 - P2765 魔术球问题(最大流+残余网络上的最大流+路径打印)
  2. Smarty 显示大括号 | 在Smarty中计算数组元素的长度 | Smarty字符串拼接
  3. Android之解决卸载app后再次安装提示room数据库错误
  4. Ant步步为营(4)ant启动tomcat
  5. Intel 64/x86_64/IA-32/x86处理器 - 指令格式(10/E) - 特殊指令格式(AVX AVX-512)
  6. 15寸计算机显示器,苹果确认15寸RMBP支持全球首款5K显示器
  7. 【To Do! 重点 正则表达式】LeetCode 65. Valid Number
  8. orm设置bool型 python_详解python的ORM中Pony用法
  9. [杂谈]逗比的语录?
  10. 设定窗体显示状态(ShowWindow)
  11. 2016最新Java学习计划
  12. 华文行楷字帖欣赏_任政书法:行楷字帖《二十四孝组诗》集字版,美不胜收!...
  13. 冒泡 c语言,C语言:冒泡排序
  14. proguard.cfg 配置文件
  15. 分析:公众号运营+引流,怎么从0到1运营
  16. 解决Microsoft已经阻止宏运行,因为此文件的来源不受信任。
  17. gstreamer+qgc+aarch64
  18. FLASH按钮链接网页
  19. 储能逆变器,储能系统,soc均衡控制,soc均衡,蓄电池充放电控制
  20. 什么是GB/T50430

热门文章

  1. 古文字识别助手与众包平台——项目博客一
  2. 工程院院士一招防止脑中风,中老年人必学!(真人示范)
  3. 来了解一下ASN.1?
  4. Jeston nano+RealSense D455相机+ORB_SLAM3+ROS实时运行
  5. C++实现_数据分类处理(牛客网华为机试题)
  6. 多媒体课件是不是计算机软件,使用Authorware 开发的《多媒体技术》课件属于( )。...
  7. HBase 2.0.0 META 数据修复工具
  8. Revit报错:Attempting to create an ExternalEvent outside of a standard API execution
  9. /usr/bin/python: can't find '__main__' module in ''
  10. 毕业设计 - 基于JSP的超市积分管理系统【源码 + 论文】