You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native调用Flask后端下载YouTube文件失败的解决方案咨询

解决方案:Flask后端优化 + React Native客户端下载实现

一、服务端优化方案

1. 修复路由参数问题

原路由直接将视频ID作为路径参数,易触发URL编码、特殊字符解析错误,改为查询参数更安全可靠。

2. 添加跨域支持

React Native请求后端会触发跨域,需为Flask添加CORS支持,避免请求被拦截。

3. 完善错误处理与资源清理

添加异常捕获逻辑避免服务崩溃;发送文件后自动清理临时文件,防止服务器磁盘占用过高。

修改后的服务端代码

先安装依赖:

pip install flask-cors

app.py:

from flask import Flask, send_file, request, jsonify
from flask_cors import CORS
import vid_request
import os

app = Flask(__name__)
CORS(app)  # 允许跨域请求,生产环境可配置指定域名

@app.route("/download")
def download():
    video_id = request.args.get("video_id")
    if not video_id:
        return jsonify({"error": "缺少video_id参数"}), 400
    
    file_path = None
    try:
        file_path = vid_request.download(video_id, "tempDownloads")
        file_name = os.path.basename(file_path)
        # 指定MIME类型,确保客户端正确识别文件格式
        return send_file(
            file_path,
            as_attachment=True,
            download_name=file_name,
            mimetype="audio/mp4"
        )
    except Exception as e:
        return jsonify({"error": str(e)}), 500
    finally:
        # 发送完成后删除临时文件
        if file_path and os.path.exists(file_path):
            os.remove(file_path)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

vid_request.py(优化流选择与错误处理):

import pytube

def download(video_id, path):
    url = f"https://www.youtube.com/watch?v={video_id}"
    youtube_obj = pytube.YouTube(url)
    # 筛选最高质量的MP4音频流
    audio_stream = youtube_obj.streams.filter(only_audio=True, file_extension="mp4") \
                                  .order_by("abr").desc().first()
    if not audio_stream:
        raise Exception("该视频无可用音频流")
    return audio_stream.download(output_path=path)

二、React Native客户端下载实现

原生fetch不会自动处理文件下载,需手动将响应转为Blob,再写入本地文件系统。

1. 安装依赖

npm install react-native-fs
# 或
yarn add react-native-fs

2. 客户端代码示例

import RNFS from 'react-native-fs';

const downloadYouTubeAudio = async (videoId) => {
  try {
    const response = await fetch(`http://192.168.0.12:5000/download?video_id=${videoId}`);
    
    if (!response.ok) {
      const errorRes = await response.json();
      throw new Error(errorRes.error || '下载请求失败');
    }

    // 将响应转为Blob格式
    const blob = await response.blob();
    // 从响应头提取文件名
    const contentDisposition = response.headers.get('Content-Disposition');
    let fileName = 'audio.mp4';
    if (contentDisposition) {
      const nameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
      if (nameMatch?.[1]) {
        fileName = nameMatch[1].replace(/['"]/g, '');
      }
    }

    // 保存到手机下载目录
    const savePath = `${RNFS.DownloadDirectoryPath}/${fileName}`;
    // 将Blob转为Base64写入文件
    const base64Data = await new Promise(resolve => {
      const reader = new FileReader();
      reader.onloadend = () => resolve(reader.result.split(',')[1]);
      reader.readAsDataURL(blob);
    });

    await RNFS.writeFile(savePath, base64Data, 'base64');
    console.log(`文件已保存至: ${savePath}`);
    // 可在此添加用户提示,如Toast通知下载完成
  } catch (err) {
    console.error('下载出错:', err.message);
    // 提示用户错误信息
  }
};

// 调用示例:downloadYouTubeAudio('目标视频ID');

三、关键注意事项

  • 确保手机与服务器处于同一局域网,且服务器IP地址配置正确。
  • Android需在AndroidManifest.xml添加网络权限:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • iOS需允许HTTP请求,在Info.plist中添加:
    <key>NSAppTransportSecurity</key>
    <dict>
      <key>NSAllowsArbitraryLoads</key>
      <true/>
    </dict>
    
  • 定期更新pytube:YouTube接口会频繁调整,执行pip install --upgrade pytube保持依赖最新。

内容的提问来源于stack exchange,提问作者giji676

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:10:26