单个帖子(视频/图集/音乐/直播流)提取接口
Note
接口概述
该接口用于提取单个帖子的媒体内容(视频/图片/音乐/直播等),支持哼哼猫覆盖的 999+ 平台。
🎯 基本信息
| 项目 | 内容 |
|---|---|
| 接口地址 | https://api.meowload.net/openapi/extract/post |
| 请求方式 | POST |
| Content-Type | application/json |
📋 请求参数
请求头 (Headers)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
x-api-key | string | 是 | API 密钥,在 开发者管理中心 获取 |
accept-language | string | - | 错误消息语言,默认 en支持: zh、en、ja、es、de 等 |
请求体 (Body)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
url | string | 是 | 单个帖子的分享链接地址 |
请求示例
curl -X POST https://api.meowload.net/openapi/extract/post \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key-here" \
-H "accept-language: zh" \
-d '{
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}'🟢 成功响应
HTTP 状态码:
200 OK
响应示例 - 基础格式
{
"text": "Introducing Opera One https://t.co/ABHoIW116d",
"medias": [
{
"media_type": "video",
"resource_url": "https://video.twimg.com/ext_tw_video/1650757905975595010/pu/vid/1280x720/HhaDnQS7feVgqhAN.mp4?tag=12",
"preview_url": "https://pbs.twimg.com/ext_tw_video_thumb/1650757905975595010/pu/img/t5yBiZFRPAIa_4Pi.jpg"
},
{
"media_type": "image",
"resource_url": "https://example.com/image.jpg",
"preview_url": null
},
{
"media_type": "audio",
"resource_url": "https://example.com/audio.m4a",
"preview_url": "https://example.com/cover.jpg",
"headers": {
"Referer": "https://www.example.com/",
"User-Agent": "Mozilla/5.0 (compatible; MSIE Version; Operating System)"
}
}
],
"id": "1650758247739949056",
"created_at": "Tue Apr 25 07:06:50 +0000 2023"
}响应示例 - 多清晰度格式
Tip
多清晰度支持
部分平台(如 YouTube、Facebook)的视频会包含多个清晰度版本,以 formats 字段返回。
💡 点击展开查看多清晰度响应示例
{
"text": "10个PC必装的免费软件,既个性又好用",
"medias": [
{
"media_type": "video",
"resource_url": "https://googlevideo.com/videoplayback?ei=L92YYsOeF9nbkgatuKvoDg",
"preview_url": "https://i.ytimg.com/vi/WKSZXFvpu5Q/maxresdefault.jpg",
"formats": [
{
"quality": 2160,
"video_url": "https://googlevideo.com/pl5h1V3m4CIQCO6O9Dk.webm",
"video_ext": "webm",
"video_size": 24532741513,
"audio_url": "https://googlevideo.com/V3m4CIQCO6O9Dk7TPDllq.m4a",
"audio_ext": "m4a",
"audio_size": 221231911,
"separate": 1,
"quality_note": "4K"
},
{
"quality": 1440,
"video_url": "https://googlevideo.com/QCO6O9Dk7TPDllq.webm",
"video_ext": "webm",
"video_size": 12547654223,
"audio_url": "https://googlevideo.com/V3m4CIQCO6O.m4a",
"audio_ext": "m4a",
"audio_size": 221231911,
"separate": 1,
"quality_note": "2K"
},
{
"quality": 1080,
"video_url": "https://googlevideo.com/V3m4CIQCO6O9Dk7.mp4",
"video_ext": "mp4",
"video_size": 5995725852,
"audio_url": "https://googlevideo.com/IQCO6O9Dk7TP.m4a",
"audio_ext": "m4a",
"audio_size": 221231911,
"separate": 1,
"quality_note": "HD"
},
{
"quality": 720,
"video_url": "https://googlevideo.com/m4CIQCO6O9Dk7TPDllq.mp4",
"video_ext": "mp4",
"video_size": 2849049722,
"audio_url": null,
"audio_ext": null,
"audio_size": 0,
"separate": 0,
"quality_note": null
},
{
"quality": 480,
"video_url": "https://googlevideo.com/V3m4CIQCO6O9Dk7T.mp4",
"video_ext": "mp4",
"video_size": 1306363594,
"audio_url": "https://googlevideo.com/JFTso7rYNu_Qtjpl5h1V.m4a",
"audio_ext": "m4a",
"audio_size": 221231911,
"separate": 1,
"quality_note": null
}
]
}
]
}响应字段说明
| 字段 | 类型 | 必返回 | 说明 |
|---|---|---|---|
text | string | - | 帖子文案内容 |
id | string | - | 帖子唯一标识 ID |
created_at | string | - | 帖子创建时间 |
medias | array | 是 | 媒体资源列表(一个链接可能包含多个媒体) |
medias 数组字段
| 字段 | 类型 | 必返回 | 说明 |
|---|---|---|---|
media_type | string | 是 | 媒体类型video(视频)、image(图片)、audio(音频)、live(直播)、file(未知文件类型) |
resource_url | string | 是 | 媒体资源下载地址 |
preview_url | string | - | 封面/预览图地址(视频/音频/直播) |
headers | object | - | 下载时需要携带的请求头 (部分平台需要) |
formats | array | - | 多清晰度版本列表 (YouTube、Facebook 等平台) |
formats 数组字段(多清晰度)
| 字段 | 类型 | 说明 |
|---|---|---|
quality | number | 视频清晰度(高度像素,如 1080、720) |
quality_note | string | 清晰度标注(如 “4K”、“2K”、“1080p”、“360p”) |
video_url | string | 视频流地址 |
video_ext | string | 视频文件扩展名(如 mp4、webm) |
video_size | number | 视频文件大小(字节) |
audio_url | string | 音频流地址(音视频分离时存在) |
audio_ext | string | 音频文件扩展名(如 m4a、mp3) |
audio_size | number | 音频文件大小(字节) |
separate | number | 是否音视频分离1(分离)、0(不分离) |
🔴 错误响应
HTTP 状态码:非
200(如 400、401、402、422、500)
错误响应示例
{
"message": "链接格式错误"
}HTTP 状态码说明
| 状态码 | 说明 | 常见原因 | 解决方案 |
|---|---|---|---|
200 | 成功 | - | - |
400 | 业务失败 | 解析失败,链接不包含有效媒体 | 检查链接是否正确,是否包含视频/图片等 |
401 | 鉴权失败 | API Key 无效或过期 | 检查 x-api-key 是否正确 |
402 | 次数用尽 | 调用额度已用完 | 前往 管理中心 充值 |
422 | 参数错误 | 链接格式不正确 | 检查 url 参数格式 |
500 | 服务器错误 | 服务器内部异常 | 联系技术支持 |
💻 代码示例
Python
import requests
api_url = "https://api.meowload.net/openapi/extract/post"
api_key = "your-api-key-here"
payload = {
"url": "https://www.bilibili.com/video/BV1sG4y1p7TA/"
}
headers = {
"x-api-key": api_key,
"accept-language": "zh"
}
response = requests.post(api_url, json=payload, headers=headers)
if response.status_code == 200:
data = response.json()
print("✅ 提取成功!")
print(f"文案: {data.get('text', '无')}")
print(f"媒体数量: {len(data['medias'])}")
for idx, media in enumerate(data['medias'], 1):
print(f"\n--- 媒体 {idx} ---")
print(f"类型: {media['media_type']}")
print(f"下载地址: {media['resource_url']}")
else:
error = response.json()
print(f"❌ 请求失败 ({response.status_code}): {error['message']}")JavaScript (Fetch)
const apiUrl = "https://api.meowload.net/openapi/extract/post";
const apiKey = "your-api-key-here";
const payload = {
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
};
const headers = {
"Content-Type": "application/json",
"x-api-key": apiKey,
"accept-language": "zh"
};
fetch(apiUrl, {
method: "POST",
headers: headers,
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) {
return response.json().then(error => {
throw new Error(`${response.status}: ${error.message}`);
});
}
return response.json();
})
.then(data => {
console.log("✅ 提取成功!");
console.log(`文案: ${data.text || '无'}`);
console.log(`媒体数量: ${data.medias.length}`);
data.medias.forEach((media, idx) => {
console.log(`\n--- 媒体 ${idx + 1} ---`);
console.log(`类型: ${media.media_type}`);
console.log(`下载地址: ${media.resource_url}`);
});
})
.catch(error => {
console.error(`❌ 请求失败: ${error.message}`);
});Golang
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
type ExtractRequest struct {
URL string `json:"url"`
}
type Media struct {
MediaType string `json:"media_type"`
ResourceURL string `json:"resource_url"`
PreviewURL string `json:"preview_url,omitempty"`
}
type ExtractResponse struct {
Text string `json:"text,omitempty"`
Medias []Media `json:"medias"`
ID string `json:"id,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
}
type ErrorResponse struct {
Message string `json:"message"`
}
func main() {
apiURL := "https://api.meowload.net/openapi/extract/post"
apiKey := "your-api-key-here"
// 构造请求体
requestBody := ExtractRequest{
URL: "https://www.bilibili.com/video/BV1sG4y1p7TA/",
}
jsonData, err := json.Marshal(requestBody)
if err != nil {
fmt.Printf("❌ JSON 序列化失败: %v\n", err)
return
}
// 创建 HTTP 请求
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
if err != nil {
fmt.Printf("❌ 创建请求失败: %v\n", err)
return
}
// 设置请求头
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-api-key", apiKey)
req.Header.Set("accept-language", "zh")
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("❌ 发送请求失败: %v\n", err)
return
}
defer resp.Body.Close()
// 读取响应
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Printf("❌ 读取响应失败: %v\n", err)
return
}
// 处理响应
if resp.StatusCode == 200 {
var result ExtractResponse
if err := json.Unmarshal(body, &result); err != nil {
fmt.Printf("❌ 解析响应失败: %v\n", err)
return
}
fmt.Println("✅ 提取成功!")
fmt.Printf("文案: %s\n", result.Text)
fmt.Printf("媒体数量: %d\n", len(result.Medias))
for idx, media := range result.Medias {
fmt.Printf("\n--- 媒体 %d ---\n", idx+1)
fmt.Printf("类型: %s\n", media.MediaType)
fmt.Printf("下载地址: %s\n", media.ResourceURL)
}
} else {
var errorResp ErrorResponse
if err := json.Unmarshal(body, &errorResp); err != nil {
fmt.Printf("❌ 解析错误响应失败: %v\n", err)
return
}
fmt.Printf("❌ 请求失败 (%d): %s\n", resp.StatusCode, errorResp.Message)
}
}PHP
<?php
$apiUrl = "https://api.meowload.net/openapi/extract/post";
$apiKey = "your-api-key-here";
$params = array(
"url" => "https://www.tiktok.com/@nike/video/7198345395863309611"
);
$options = array(
"http" => array(
"header" =>
"Content-Type: application/json\r\n" .
"x-api-key: " . $apiKey . "\r\n" .
"accept-language: zh",
"method" => "POST",
"content" => json_encode($params),
),
"ssl" => array(
"verify_peer" => false,
"verify_peer_name" => false,
),
);
$context = stream_context_create($options);
$response = file_get_contents($apiUrl, false, $context);
// 解析 HTTP 响应状态码
$statusLine = $http_response_header[0];
preg_match('{HTTP\/\S*\s(\d{3})}', $statusLine, $match);
$statusCode = $match[1];
$data = json_decode($response, true);
if ($statusCode == 200) {
echo "✅ 提取成功!\n";
echo "文案: " . ($data['text'] ?? '无') . "\n";
echo "媒体数量: " . count($data['medias']) . "\n";
foreach ($data['medias'] as $idx => $media) {
echo "\n--- 媒体 " . ($idx + 1) . " ---\n";
echo "类型: " . $media['media_type'] . "\n";
echo "下载地址: " . $media['resource_url'] . "\n";
}
} else {
echo "❌ 请求失败 (" . $statusCode . "): " . $data['message'] . "\n";
}
?>💡 使用技巧
1. 处理带自定义请求头的媒体
部分平台的媒体资源需要携带特定的 HTTP Headers 才能下载:
import requests
# 假设 API 返回的 media 包含 headers 字段
media = {
"media_type": "audio",
"resource_url": "https://example.com/audio.m4a",
"headers": {
"Referer": "https://www.example.com/",
"User-Agent": "Mozilla/5.0..."
}
}
# 下载时携带这些 headers
if media.get('headers'):
response = requests.get(media['resource_url'], headers=media['headers'])
else:
response = requests.get(media['resource_url'])
with open('downloaded_file.m4a', 'wb') as f:
f.write(response.content)2. 选择合适的视频清晰度
对于支持多清晰度的视频,根据需求选择合适的版本:
def select_quality(formats, target_quality=1080):
"""
从 formats 列表中选择最接近目标清晰度的版本
"""
if not formats:
return None
# 按清晰度排序
sorted_formats = sorted(formats, key=lambda x: abs(x['quality'] - target_quality))
return sorted_formats[0]
# 使用示例
if 'formats' in media:
selected = select_quality(media['formats'], target_quality=1080)
print(f"选择清晰度: {selected['quality']}p ({selected.get('quality_note', '')})")
print(f"视频地址: {selected['video_url']}")3. 音视频分离处理
某些高清视频的音视频是分离的,需要分别下载后合并:
def download_and_merge(format_item):
"""
下载并合并分离的音视频(需要 ffmpeg)
"""
import subprocess
if format_item['separate'] == 1:
# 下载视频
video_file = "video.mp4"
audio_file = "audio.m4a"
output_file = "merged.mp4"
# ... 下载 video_url 到 video_file
# ... 下载 audio_url 到 audio_file
# 使用 ffmpeg 合并
subprocess.run([
'ffmpeg',
'-i', video_file,
'-i', audio_file,
'-c', 'copy',
output_file
])
print(f"✅ 合并完成: {output_file}")
else:
# 音视频一体,直接下载
print("音视频一体,无需合并")