鸿蒙开发仓颉语言:音视频开发—— mp3tag4cj

📌往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)

📃 鸿蒙(HarmonyOS)北向开发知识点记录~

📃 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

📃 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

📃 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

📃 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

📃 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

📃 记录一场鸿蒙开发岗位面试经历~

📃 持续更新中……


介绍

一个用于读取mp3文件和读取/操作ID3标记(ID3v1和ID3v2.2到ID3v2.4)的库。

特性

  • 🚀 特性1

读取、写入、添加和删除ID3v1标签。

  • 🚀 特性2

读取、写入、添加和删除ID3v2标签,标签表示内容支持ISO-8859-1,UTF-16LE,UTF-16BE,UTF-8 4种编码; 读取音频数据帧帧头包含的数据信息; 判断vbr文件,获得每个音频数据帧的位率;在音频数据帧结尾和ID3v1标记之间添加或删除自定义标签。

路线

软件架构

架构图

源码目录

.
├── README.md
├── CHANGELOG.md
├── README.OPENSOURCE
├── mit-license.txt
├── doc
│   ├── assets
│   └── feature_api.md
├── src
│   └── mp3tag4cj 
│       ├──abstract_id3v2_frame_data.cj
│       ├──abstract_id3v2_tag.cj
│       ├──base_exception.cj
│       ├──buffer_tools.cj
│       ├──encoded_text.cj
│       ├──file_wrapper.cj
│       ├──id3v1.cj
│       ├──id3v1_genres.cj
│       ├──id3v1_tag.cj
│       ├──id3v2.cj
│       ├──id3v2_frame.cj
│       ├──id3v2_frame_set.cj
│       ├──id3v2_obselete_frame.cj
│       ├──id3v2_tag_factory.cj
│       ├──id3v2_text_frame_data.cj
│       ├──id3v22_tag.cj
│       ├──id3v23_tag.cj
│       ├──id3v24_frame.cj
│       ├──id3v24_tag.cj
│       ├──invalid_data_exception.cj
│       ├──mp3_file.cj
│       ├──mpeg_frame.cj
│       ├──mutable_integer.cj
│       ├──no_such_tag_exception.cj
│       ├──not_supported_exception.cj
│       └──unsupported_tag_exception.cj
│   └── package.cj 
└── test
    ├── HLT 
    ├── LLT
    └── UT

  • doc是库的设计文档、提案、库的使用文档、LLT 覆盖率报告
  • src是库源码目录
  • test是测试用例所在目录,包括HLT用例、LLT 用例和UT用例

使用说明

编译

cjpm build

使用示例

注意,请记得配置MP3文件路径

对ID3V1标签的设置、获取和保存

获取和设置IDCV1标签数据:

import std.io.*
import mp3tag4cj.mp3tag4cj.*
import charset4cj.charset.*
import charset4cj.charset.singlebyte.*
import charset4cj.charset.encoding.*

main() {
    var file = FileInfo("../../../../test/LLT/testFile/v1tag.mp3")
    var mp3File = Mp3File(file)
    if (mp3File.hasId3v1Tag()){
        var id3v1Tag = mp3File.getId3v1Tag().getOrThrow()
        showId3v1(id3v1Tag)
        id3v1Tag.setTrack(Option<String>.Some(""))
        id3v1Tag.setArtist(Option<String>.Some("NEWARTIST12345678901234567890"))
        id3v1Tag.setTitle(Option<String>.Some("NEWTITLE12345678901234567890"))
        id3v1Tag.setAlbum(Option<String>.Some("NEWALBUM1234567890123456789011111111111111111111111111"))
        id3v1Tag.setYear(Option<String>.Some("19940821"))
        id3v1Tag.setGenre(Option<Int64>.Some(20))
        id3v1Tag.setComment(Option<String>.Some("NEWCOMMENT123456"))
    }
    mp3File.save("../../../../test/LLT/testFile/v1tagNew.mp3")
    var file2 = FileInfo("../../../../test/LLT/testFile/v1tagNew.mp3")
    var mp3FileNew = Mp3File(file2)
    if (mp3FileNew.hasId3v1Tag()){
        var id3v1Tag = mp3FileNew.getId3v1Tag().getOrThrow()
        showId3v1(id3v1Tag)
        checkId3v1(id3v1T)
    }
    File.delete("../../../../test/LLT/testFile/v1tagNew.mp3")
    0
}
func checkId3v1(id3v1Tag: ID3v1){
    if (id3v1Tag.getVersion() != "0") {
        throw RuntimeException("Expected non conformance")
    }
    if (id3v1Tag.getTrack() != "") {
        throw RuntimeException("Expected non conformance")
    }
    if (id3v1Tag.getArtist() != "NEWARTIST12345678901234567890") {
        throw RuntimeException("Expected non conformance")
    }
    if (id3v1Tag.getTitle() != "NEWTITLE12345678901234567890") {
        throw RuntimeException("Expected non conformance")
    }
    if (id3v1Tag.getAlbum() != "NEWALBUM1234567890123456789011") {
        throw RuntimeException("Expected non conformance")
    }
    if (id3v1Tag.getYear() != "1994") {
        throw RuntimeException("Expected non conformance")
    }
    if (id3v1Tag.getGenre() != 20) {
        throw RuntimeException("Expected non conformance")
    }
    if (id3v1Tag.getComment() != "NEWCOMMENT123456") {
        throw RuntimeException("Expected non conformance")
    }
    if (id3v1Tag.getGenreDescription() != "Alternative") {
        throw RuntimeException("Expected non conformance")
    }
}

func showId3v1(id3v1Tag: ID3v1) {
    var version = id3v1Tag.getVersion()
    var track = id3v1Tag.getTrack()
    var artist = id3v1Tag.getArtist()
    var title = id3v1Tag.getTitle()
    var album = id3v1Tag.getAlbum()
    var year = id3v1Tag.getYear()
    var genre = id3v1Tag.getGenre()
    var des = id3v1Tag.getGenreDescription()
    var comm = id3v1Tag.getComment()
    println("version ==> ${version}")
    println("track ==> ${track}")
    println("artist ==> ${artist}")
    println("title ==> ${title}")
    println("album ==> ${album}")
    println("year ==> ${year}")
    println("genre ==> ${genre}")
    println("comm ==> ${comm}")
    println("des ==> ${des}")
}

执行结果如下:

执行结果:
version ==> 1
track ==> Some(1)
artist ==> Some(ARTIST123456789012345678901234)
title ==> Some(TITLE1234567890123456789012345)
album ==> Some(ALBUM1234567890123456789012345)
year ==> Some(2001)
genre ==> Some(13)
comm ==> Some(COMMENT123456789012345678901)
des ==> Pop
version ==> 0
track ==> Some()
artist ==> Some(NEWARTIST12345678901234567890)
title ==> Some(NEWTITLE12345678901234567890)
album ==> Some(NEWALBUM1234567890123456789011)
year ==> Some(1994)
genre ==> Some(20)
comm ==> Some(NEWCOMMENT123456)
des ==> Alternative

获取MP3音频数据相关成员

import mp3tag4cj.mp3tag4cj.*
import std.collection.*
import std.io.*
import mp3tag4cj.mp3tag4cj.*
import charset4cj.charset.*
import charset4cj.charset.singlebyte.*
import charset4cj.charset.encoding.*

main() {
    //v1andv23andcustomtags.mp3
    var mp3File: Mp3File = Mp3File("../../../../test/LLT/id3v2Test/testv2File/v1andv23andcustomtags.mp3")
    var startOffset:Int32 = mp3File.getStartOffset()
    var xingOffset:Int32 = mp3File.getXingOffset()
    var endOffset:Int32 = mp3File.getEndOffset()
    var frameCount:Int32 = mp3File.getFrameCount()
    var bitrate:Int32 = mp3File.getBitrate()
    var xingBitrate:Int32 = mp3File.getXingBitrate()
    var bitrates: Map<Int32, MutableInteger> = mp3File.getBitrates()
    var channelMode: String = mp3File.getChannelMode()
    var emphasis: String = mp3File.getEmphasis()
    var layer: String = mp3File.getLayer()
    var lengthInMilliseconds: Int64 = mp3File.getLengthInMilliseconds()
    var lengthInSeconds: Int64 = mp3File.getLengthInSeconds()
    var modeExtension: String = mp3File.getModeExtension()
    var sampleRate: Int32 = mp3File.getSampleRate()
    var version: String = mp3File.getVersion()
    var copyright: Bool = mp3File.isCopyright()
    var original: Bool = mp3File.isOriginal()
    var vbr: Bool = mp3File.isVbr()
    println("startOffset ===> ${startOffset}")
    println("xingOffset ===> ${xingOffset}")
    println("endOffset ===> ${endOffset}")
    println("frameCount ===> ${frameCount}")
    println("bitrate ===> ${bitrate}")
    println("xingBitrate ===> ${xingBitrate}")
    println("channelMode ===> ${channelMode}")
    println("emphasis ===> ${emphasis}")
    println("layer ===> ${layer}")
    println("lengthInMilliseconds ===> ${lengthInMilliseconds}")
    println("lengthInSeconds ===> ${lengthInSeconds}")
    println("modeExtension ===> ${modeExtension}")
    println("sampleRate ===> ${sampleRate}")
    println("version ===> ${version}")
    println("copyright ===> ${copyright}")
    println("original ===> ${original}")
    println("vbr ===> ${vbr}")
    for ( (k,v) in bitrates ){
        println("bitrates key ===> ${k}")
        println("bitrates val ===> ${v.getValue()}")
    }
    0
}

执行结果如下:

执行结果:
startOffset ===> 1516
xingOffset ===> 1099
endOffset ===> 3967
frameCount ===> 6
bitrate ===> 125
xingBitrate ===> 128
channelMode ===> Joint stereo
emphasis ===> None
layer ===> III
lengthInMilliseconds ===> 156
lengthInSeconds ===> 0
modeExtension ===> None
sampleRate ===> 44100
version ===> 1.0
copyright ===> false
original ===> true
vbr ===> true
bitrates key ===> 224
bitrates val ===> 1
bitrates key ===> 112
bitrates val ===> 1
bitrates key ===> 96
bitrates val ===> 2
bitrates key ===> 192
bitrates val ===> 1
bitrates key ===> 32
bitrates val ===> 1

约束与限制

在下述版本验证通过:

Cangjie Version: 0.53.4
面对成千上万首 mp3 资源,快速为它们统一编辑歌曲属性是不少朋友关心的问题.借用微软 Access 数据库工具,能让这个愿望成为切实可行的办法! 生成数据库步骤 一,在Mp3tag下 1,确保标签栏字段“Filename”数据输入完整,Mp3tag系统将以此栏数据作为排序依据; 2,选中全部内容; 3,点选“文件-导出”,选中“CSV”格式,即 Microsoft Office Excel 逗号分隔值文件。 二,在Excel下 1,新建空文件; 2,点选菜单栏“数据-导入外部数据-导入数据”,在弹出的窗口里选择工作目录,在文件类型选择框里选中“所有数据源”,刚生成CSV格式文件将显现出来,选中并确定之; 3,在第一个选择窗原始数据类型提示中确认选中“分隔符号”而非“固定宽度”,下一步; 4,在第二个选择窗分隔符号提示中确认选中“分号”而非其它,选择后可见待导入的内容已被分隔成多列。下一步; 5,点选相应各列并设置“常规”、“文本”、“日期”或“不导入此列(跳过)”; 6,点击“完成”按钮,确认数据的放置位置选择为“现有工作表”而非新建工作表并确定之。 7,粗查导入的数据,其顺序应与在Mp3tag下略有不同,但可见到完整各列,完全符合Access的要求。如果发现问题,应返回到Mp3tag下修改,然后返回第一步开始。 8,检查无误,即可存盘,应用另存为方式存为默认的 Microsoft Office Excel 工作薄。存盘后将会有后缀为xls的文件。 三,在Access下 1,首先建立一个空文档,即新建一个空数据库;文件名选在工作目录并命名; 2,点选“文件-获取外部数据-导入”,在导入文件类型选择框中选择 Microsoft Excel 类型,然后选中刚生成的xls工作表文件。 3,在新窗口取默认的“Sheet1”为工作表区域;下一步; 4,确认新窗口的“第一行包括列标题”为勾选状态,下一步; 5,确认新窗口的“数据库保存位置”为新表中,下一步; 6,新窗口的“字段选项”可忽略,下一步; 7,确认新窗口“为新表定义一个主键”选项里处于默认的“让Access添加主键”为选中状态,下一步; 8,在新窗口点击“完成钮” 9,由于数据源的Year字段可能存在非标格式数据,这些数据将不能被正常导入,对本工作来讲可予忽略。 经过以上步骤,我们已经完成了期待的目标和工作,恭喜你! 老冯 2015-6-12 改写
MP3文件ID3-Tag信息修改器。所谓ID3-Tag 信息,就是在MP3文件中加入曲名,演唱者,专辑,年月,流派,注释等信息,便于您收集歌曲。其实winamp中带有编辑器,只是把它做的方便一点。 Mp3tag[4]可以以文件名批量添加媒体元信息,根据媒体元信息批量重命名文件,执行批量文字替换、导入导出文件信息、创建播放列表等任务。 MP3tag软件运行批量修改,免去了大家一个一个修改的麻烦,也解决了播放MP3出现乱码。 一mp3tag怎么用 1。打开你MP3文件所在的文件目录 步骤:菜单中“文件“ - ”改变目录“,此时会出现文件目录选择,选择上你MP3所在的目录。 技巧:可以采用”更改目录“菜单,则下一次启动的时候,就自动打开你更改过的目录。 2。选择要更改的文件。 步骤:打开目录后,在右面的列表中会出现MP3文件,选择你要更改的MP3音乐,右键点击就可以。 技巧:可以按住CTRL键进行多个选择、或按住SHIFT键进行一排进择。 3。移除标签 步骤:菜单中“文件“ - ”移除标签“,则把你所选择的MP3的标签清除。 上述的几个命令,在工具栏上都有,懒得贴出来,大家自己找。想要标签的朋友,可以选择MP3文件,然后进行编辑后保存。也可以 批量修改,依照正则表达式规格,命令在"转换" - “文件名到标签”。 软件功能 1.一次对对多个文件写入 ID3v1.1、 ID3v2、APEv2等标签。 2.自动创建列表。 3.支持扫描子文件夹 4.删除多个文件的部分或者这个标签内容。 5.给予标签信息重命名文件。 6.从文件名导入标签 7.格式化标签和文件名 8.用标签和文件名替换字符 9.输出标签信息为用户定义的格式 10.从在线数据库导入标签信息 11.从本地数据库导入标签信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值