fix:m4a无法正确获取播放时长
This commit is contained in:
parent
ae34572d13
commit
406e09922c
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
import asyncio
|
import asyncio
|
||||||
import copy
|
import copy
|
||||||
import difflib
|
import difflib
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
@ -189,6 +190,13 @@ def is_mp3(url):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def is_m4a(url):
|
||||||
|
mt = mimetypes.guess_type(url)
|
||||||
|
if mt and mt[0] == "audio/m4a":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
async def _get_web_music_duration(session, url, start=0, end=500):
|
async def _get_web_music_duration(session, url, start=0, end=500):
|
||||||
duration = 0
|
duration = 0
|
||||||
headers = {"Range": f"bytes={start}-{end}"}
|
headers = {"Range": f"bytes={start}-{end}"}
|
||||||
@ -199,6 +207,8 @@ async def _get_web_music_duration(session, url, start=0, end=500):
|
|||||||
try:
|
try:
|
||||||
if is_mp3(url):
|
if is_mp3(url):
|
||||||
m = mutagen.mp3.MP3(tmp)
|
m = mutagen.mp3.MP3(tmp)
|
||||||
|
elif is_m4a(url):
|
||||||
|
return get_duration_by_ffprobe(tmp)
|
||||||
else:
|
else:
|
||||||
m = mutagen.File(tmp)
|
m = mutagen.File(tmp)
|
||||||
duration = m.info.length
|
duration = m.info.length
|
||||||
@ -244,6 +254,9 @@ async def get_local_music_duration(filename):
|
|||||||
try:
|
try:
|
||||||
if is_mp3(filename):
|
if is_mp3(filename):
|
||||||
m = await loop.run_in_executor(None, mutagen.mp3.MP3, filename)
|
m = await loop.run_in_executor(None, mutagen.mp3.MP3, filename)
|
||||||
|
elif is_m4a(filename):
|
||||||
|
duration = get_duration_by_ffprobe(filename)
|
||||||
|
return duration
|
||||||
else:
|
else:
|
||||||
m = await loop.run_in_executor(None, mutagen.File, filename)
|
m = await loop.run_in_executor(None, mutagen.File, filename)
|
||||||
duration = m.info.length
|
duration = m.info.length
|
||||||
@ -252,6 +265,27 @@ async def get_local_music_duration(filename):
|
|||||||
return duration
|
return duration
|
||||||
|
|
||||||
|
|
||||||
|
def get_duration_by_ffprobe(file_path):
|
||||||
|
# 使用 ffprobe 获取文件的元数据,并以 JSON 格式输出
|
||||||
|
result = subprocess.run(
|
||||||
|
[ os.path.join(os.getenv("XIAOMUSIC_FFMPEG_LOCATION", "./ffmpeg/bin"),"ffprobe"),
|
||||||
|
"-v", "error", # 只输出错误信息,避免混杂在其他输出中
|
||||||
|
"-show_entries", "format=duration", # 仅显示时长
|
||||||
|
"-of", "json", # 以 JSON 格式输出
|
||||||
|
file_path
|
||||||
|
],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
universal_newlines=True
|
||||||
|
)
|
||||||
|
|
||||||
|
# 解析 JSON 输出
|
||||||
|
ffprobe_output = json.loads(result.stdout)
|
||||||
|
|
||||||
|
# 获取时长
|
||||||
|
duration = float(ffprobe_output['format']['duration'])
|
||||||
|
|
||||||
|
return duration
|
||||||
def get_random(length):
|
def get_random(length):
|
||||||
return "".join(random.sample(string.ascii_letters + string.digits, length))
|
return "".join(random.sample(string.ascii_letters + string.digits, length))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user