>백엔드 개발 >파이썬 튜토리얼 >Python을 이용한 mp3형식판정에 대한 자세한 설명

Python을 이용한 mp3형식판정에 대한 자세한 설명

高洛峰
高洛峰원래의
2017-02-23 16:36:041920검색

프로젝트에서는 효과음 재생을 위해 mp3 형식을 사용하는데, 프로그램에서 재생할 수 없는 mp3 파일을 만나보니 wav 형식의 파일인데 mp3로 끝나는군요. 리소스의 mp3 형식을 판단하려면 어떻게 해야 합니까? .mp3 접미사를 사용하는 것은 확실히 신뢰할 수 없습니다. 인코딩 형식으로 판단해야 합니다.

1.mp3 인코딩

MP3 파일은 스트리밍 미디어 파일 형식이므로 파일 헤더가 없습니다. AVI 및 WAV와 같은 파일 헤더가 있는 형식은 모두 RIFF로 시작합니다. RIFF 문자열을 비교하면 AVI인지 WAV인지 알 수 있지만 mp3는 인코딩 형식만 분석할 수 있습니다. mp3 인코딩 규칙에 대해 간략하게 소개합니다.

MP3 파일은 일반적으로 TAG_V2(ID3V2), 오디오 데이터, TAG_V1(ID3V1)

세 부분으로 나뉩니다.

a) ID3V2는 파일의 시작 부분에 ID3으로 시작하며 작가, 작곡가, 앨범 등의 정보를 포함합니다. 길이는 고정되어 있지 않으며 ID3V1의 정보량을 확장하며 선택 사항입니다.

b) 일련의 오디오 데이터 프레임, 파일 중간에 번호는 파일 크기와 프레임 길이에 따라 결정됩니다. 각 프레임은 FFF로 시작하며 길이가 고정되지 않을 수 있습니다. 고정되어 있으며 각 프레임은 프레임 헤더로 나누어지며 프레임 헤더는 mp3의 비트율, 샘플링 속도, 버전 및 기타 정보를 기록하며 각 프레임은 독립적입니다. 서로.

c) ID3V1은 파일 끝에 TAG로 시작하며 작가, 작곡가, 앨범 등의 정보를 포함합니다. 길이는 128바이트이며 선택 사항입니다.


ID3V2

ID3V2

包含了作者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量。

Frame

.

.

.

Frame

一系列的帧,个数由文件大小和帧长决定

每个FRAME的长度可能不固定,也可能固定,由位率bitrate决定

每个FRAME又分为帧头和数据实体两部分

帧头记录了mp3的位率,采样率,版本等信息,每个帧之间相互独立。

ID3V1

包含了作者,作曲,专辑等信息,长度为128BYTE。 

작가, 작곡가, 앨범 및 기타 정보가 포함되어 있으며 길이는 고정되어 있지 않아 ID3V1의 정보량을 확장합니다.

프레임

.

.

.

프레임

일련의 프레임, 개수는 파일 크기와 프레임 길이에 따라 결정됩니다


각 FRAME의 길이는 고정되지 않을 수도 있고 고정될 수도 있으며 비트레이트에 따라 결정됩니다.

각 FRAME은 프레임 헤더와 데이터 엔터티의 두 부분으로 나뉩니다프레임 헤더는 mp3 속도, 샘플링 속도, 버전 및 기타 정보의 비트를 기록하며 각 프레임은 서로 독립적입니다.

ID3V1

작가, 작곡가, 앨범 및 기타 정보를 포함하며 길이는 128BYTE입니다.

즉, TAG_V2(ID3V2), 오디오 데이터, TAG_V1(ID3V1) 3가지 구조의 시작 정보를 기반으로, mp3로 인코딩된 파일인지 확인할 수 있습니다. 2.python 코드
# coding: utf-8

'''
@author: BigFengFeng
@time: 16/12/21 下午6:10
@license: Apache Licence
@description:

'''

import os

#mp3filePath是否是mp3格式的
def isMp3Format(mp3filePath):
 #读取文件内字符串
 f = open(mp3filePath, "r");
 fileStr = f.read();
 f.close();
 head3Str = fileStr[:3];

 #判断开头是不是ID3
 if head3Str == "ID3":
  return True;

 #判断结尾有没有TAG
 last32Str = fileStr[-32:];
 if last32Str[:3] == "TAG":
  return True;

 #判断第一帧是不是FFF开头, 转成数字
 # fixme 应该循环遍历每个帧头,这样才能100%判断是不是mp3
 ascii = ord(fileStr[:1]);
 if ascii == 255:
  return True;

 return False;


#遍历folderPath看看是不是都是mp3格式的,
#是就true,不是就是false, 并返回是mp3的list,不是MP3的list
def isMp3FolderTraverse(folderPath):
 mp3List = [];
 notMp3List = [];
 isAllMpFormat = True;
 for dirpath, dirnames, filenames in os.walk(folderPath):
  for filename in filenames:
   path = dirpath + os.sep + filename;
   isMp3 = isMp3Format(path);
   #判断是不是mp3结尾的 并且 是mp3格式的
   if isMp3 == False and str.endswith(path, ".mp3") == True:
    # print("--warning: file " + path + " is not mp3 format!--");
    notMp3List.append(path);
    isAllMpFormat = False;
   else:
    mp3List.append(path);
 return isAllMpFormat, mp3List, notMp3List;


if __name__ == '__main__':
 isMp3Format("s_com_click1.mp3");
 isAllMp3, mp3List, notMp3List = isMp3FolderTraverse("sound");
 print isAllMp3;
 print mp3List;
 print notMp3List;
위 내용이 모두에게 도움이 되기를 바랍니다. PHP 중국어 웹사이트를 지원해주세요. 파이썬을 이용한 mp3 형식 판단에 대한 자세한 설명은 PHP 중국어 홈페이지를 참고해주세요!
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.