如何在 swift 5.3 中从 m4a 音频文件中获取 Track Id

Posted

技术标签:

【中文标题】如何在 swift 5.3 中从 m4a 音频文件中获取 Track Id【英文标题】:How to get Track Id from m4a audio file in swift 5.3 【发布时间】:2021-01-05 17:59:06 【问题描述】:

我可以从音轨中获取一些信息,但不能从音轨 ID 中获取。有人指点我如何获取曲目ID吗?我正在使用 xcode 12.3。谢谢!

func getM4aAudioDetails(afile: URL) 

        let song = Song(context: moc)
        let avasset = AVAsset(url: afile as URL) as AVAsset
        let metadata = avasset.metadata(forFormat: AVMetadataFormat.iTunesMetadata)
        let cmetadata = avasset.commonMetadata

        let titleItems = AVMetadataItem.metadataItems(from: metadata, withKey: "©nam", keySpace: AVMetadataKeySpace(rawValue: "itsk"))
        if let data = titleItems.first, let title = data.stringValue 
            song.title = title
        

        let artistItems = AVMetadataItem.metadataItems(from: metadata, withKey: "©ART", keySpace: AVMetadataKeySpace(rawValue: "itsk"))
        if let data = artistItems.first, let artist = data.stringValue 
            song.artist = artist
        

        let albumItems = AVMetadataItem.metadataItems(from: metadata, withKey: "©alb", keySpace: AVMetadataKeySpace(rawValue: "itsk"))
        if let data = albumItems.first, let album = data.stringValue 
            song.album = album
        

        let trackItems = AVMetadataItem.metadataItems(from: metadata, withKey: "trkn", keySpace: AVMetadataKeySpace(rawValue: "itsk"))
        if let data = trackItems.first, let trackString = data.stringValue 
            
            song.track = Int64(trackString)!
            print("Track: \(song.track)")
        

        let artworkItems = AVMetadataItem.metadataItems(from: cmetadata, filteredByIdentifier: .commonIdentifierArtwork)
        if let artworkItem = artworkItems.first 
            if let imageData = artworkItem.dataValue 
                //let image = NSImage(data: imageData)
                song.artwork = imageData as Data
                //print("image found")
            
        
        
        print("song title: \(song.title)")
        print("song artist: \(song.artist)")
        print("song name: \(song.album)")
        print("song track: \(song.track)")
    

印刷品:(摘录)

歌名:失败者

歌曲艺术家:贝克

歌名:金黄

歌曲曲目:0

歌名:Jack-Ass

歌曲艺术家:贝克

歌名:奥德莱

歌曲曲目:0

【问题讨论】:

你所说的“track ID”是什么意思? 表示轨道号..... trkn/itsk 【参考方案1】:

您已经在trackItems 中获得了曲目编号。但是它应该是dataValue,而不是stringValue

对于我的一首曲目,我看到了 8 个字节,看起来像 4 个 16 位大端整数:

0x00000008000e0000

我的是第 8 轨,共 14 轨,所以我猜你想要第二个整数。

这里有更多关于上述的轶事证据:https://lists.apple.com/archives/cocoa-dev/2009/Oct/msg00952.html

你可以用它做你想做的事(注意keySpace/keys 的符号):

if let trackItem = AVMetadataItem.metadataItems(from: metadata, filteredByIdentifier: .iTunesMetadataTrackNumber).first,
   let data = trackItem.dataValue,
   data.count == 8 
    let bytes = [UInt8](data)
    let trackNumber = ((Int)(bytes[2]) << 8) | (Int)(bytes[3])
    let totalTracks = ((Int)(bytes[4]) << 8) | (Int)(bytes[5])
    print("trackNumber: \(trackNumber)/\(totalTracks)")

注意:mp3/ID3 是不同的,在这种情况下,您需要id3/TRCK,它是一个包含整数的stringValue

【讨论】:

不确定如何解析 trackItems 以查看您所看到的内容。如何从此代码中获取这些值``` let trackItems = AVMetadataItem.metadataItems(from: metadata, withKey: "trkn", keySpace: AVMetadataKeySpace(rawValue: "itsk"))``` if let data = trackItems.first , 让 track = data.dataValue ... 这可行,但我看不到总轨道价值。 ``` let trackItems = AVMetadataItem.metadataItems(from: metadata, withKey: "trkn", keySpace: AVMetadataKeySpace(rawValue: "itsk")) if let data = trackItems.first, let track = data.dataValue song.track = Int64(Int(track[3])) ``` 感谢您的帮助@Rhythmic Fistman。非常感谢!

以上是关于如何在 swift 5.3 中从 m4a 音频文件中获取 Track Id的主要内容,如果未能解决你的问题,请参考以下文章

修改 iTunesMetadataTrackNumber 音频文件 M4A swift

如何以 .m4a 格式录制语音

如何将m4a音频换成mp3格式

如何将m4a音频换成mp3格式

如何将两个 m4a 音频文件“混合/叠加”在一起

如何在android中录制音频m4a格式的音频文件?