Flask使用PyTube Youtube下载应用引发了JSON序列化错误

如何解决Flask使用PyTube Youtube下载应用引发了JSON序列化错误

信息:

我正在使用模块PyTube(3)构建一个Youtube Downloader Web App。 它基于Flask

其他文件的工作

使用YouTubeDownload.py文件,因此在app.py文件中,所有内容都很干净。 它用于清除不需要的数据

工作原理:

首先在索引中呈现HTML页面,其中包含带有URL输入表单的表单,该表单将其提交到“ / details”。 运行onsubmit函数以显示加载的gif。

<form action="/details" method="POST" onsubmit="navigateLoading()" id="yt-url" >
     <input placeholder="Paste video link" class="light-skinish-bg" type="url" name="url" id="url" />
</form>

然后将网址传递到yt对象,该对象是从YouTubeDownload.py的YoutubeVideo初始化的

然后使用try,除了不同的例外,它使用JINJA和stream_id传递可下载到HTML页面的流列表。

然后将流ID设置为“下载/-流的ID”。例如“下载/ 5” 因此,称为“ / download /”,它从url中获取流ID,然后根据该ID下载流,并在下载完成后运行一个名为redirectUser的函数。

重定向用户功能将bool作为str和下载的视频/音频文件名传递到HTML页面(脚本标记内部),然后将用户重定向到“ / download / f /--file -name- from js” >

然后donwload / f / filename使用flask的_directory从目录返回文件。

注意:我已经使许多变量成为全局变量,因此可以从不同的函数访问它们!

错误:

我收到的JSON类型错误完全不在上下文中,因为我没有使用它,所以似乎所有模块中都存在一些问题。

我也在下面提到错误!

app.py

from flask import Flask,request,render_template,send_from_directory,Response,redirect,flash
from YoutubeDownload import YoutubeVideo
from threading import Timer
from datetime import datetime
import os
import sys


# Flask App Initialize
app = Flask("__name__")
#App Configurations
app.secret_key = '-secret-key-'


# Global variables
yt = ""
url = ""
streams = ""
download_file_name = ""

# req vars
isAudio = False
delay_in_secs = 5
downloadStatus = False
YOUTUBE_FILES = "YouTube_Files"



# Remove the downloaded file from the directory
def removeFile(fileName):
    os.remove(os.path.join(YOUTUBE_FILES,fileName))

# Download Status to True for redirection and run remove file function
def redirectUser(stream,filepath):
    global downloadStatus,download_file_name,isAudio
    downloadStatus = True
    download_file_name = os.path.basename(filepath)
    if isAudio:
        download_file_name = os.path.splitext(download_file_name)[0] + ".mp3"
        audio_file_path = os.path.join(YOUTUBE_FILES,download_file_name)
        os.rename(filepath,audio_file_path)
    
    thread = Timer(delay_in_secs,removeFile,[download_file_name])
    thread.start()
    

# Get file extension from filename
def get_file_extension(filename):
    if not "." in filename:
        return False

    return filename.rsplit(".",1)[1].upper()


# Check whether the request was for an audio or video
def checkFileRequest(streams,stream_id):
    for i in range(len(streams)):
        if str(streams[i][0]) == str(stream_id):
            if "audio" in str(streams[i][3]):
                return True
            else:
                return False

# Index url for site
@app.route("/",methods=["GET"])
@app.route("/index")
def index():
    return render_template("index.html")

# Details on form POST request and displays streams
@app.route("/details",methods=["POST"])
def details():
    if request.method == "POST":
        try:
            yturl = request.form.get("url")
        except AttributeError as a:
            return redirect("/",404)

        global yt,streams
        try:
            yt = YoutubeVideo(yturl)
        except:
            error = sys.exc_info()
            if "get_ytplayer_config" in str(sys.exc_info()[1]):
                flash("Enter valid video url!")
                return redirect("/")
            elif "getaddrinfo failed" in str(sys.exc_info()[1]):
                network = False
                flash("Failed to get data. Please check your internet connection","danger")
                return redirect("/")
            else:
                flash(error,"danger")
                redirect("/")
        try:
            streams = yt.get_streams()
            details = yt.get_details()
        except AttributeError as e:
            flash("Enter a valid youtube url!")
            return redirect("/")
        return render_template('details.html',streams=streams,details=details)
    else:
        return redirect("/")

#On visiting this with stream id it will redirect to send it from dir
@app.route("/download/<string:stream_id>",methods=["GET"])
def download(stream_id):
    global yt,downloadStatus,streams,isAudio
    isAudio = checkFileRequest(streams,stream_id)
    try:
        yt.download_complete(redirectUser)
        yt.download(stream_id,YOUTUBE_FILES)
    except AttributeError as e:
        flash("Something went wrong,please try again!")
        return redirect("/")
    return render_template("download.html",downloadStatus=downloadStatus,fileName=download_file_name)


#Send the file from dir
@app.route("/download/f/<string:file_name>",methods=["GET"])
def returnFile(file_name):
    return send_from_directory(YOUTUBE_FILES,file_name,as_attachment=True)



@app.errorhandler(404)
def pagenotFound(error):
    return render_template("404.html")

@app.errorhandler(405)
def methodNotAllowed(error):
    return render_template("405.html")

if __name__ == "__main__":
    app.run(debug=True,port=5001)


这是错误日志:

Traceback (most recent call last):
  File "F:\Youtube Do\venv\lib\site-packages\flask\app.py",line 2464,in __call__
    return self.wsgi_app(environ,start_response)
  File "F:\Youtube Do\venv\lib\site-packages\flask\app.py",line 2450,in wsgi_app
    response = self.handle_exception(e)
  File "F:\Youtube Do\venv\lib\site-packages\flask\app.py",line 1867,in handle_exception
    reraise(exc_type,exc_value,tb)
  File "F:\Youtube Do\venv\lib\site-packages\flask\_compat.py",line 39,in reraise
    raise value
  File "F:\Youtube Do\venv\lib\site-packages\flask\app.py",line 2447,in wsgi_app
    response = self.full_dispatch_request()
  File "F:\Youtube Do\venv\lib\site-packages\flask\app.py",line 1953,in full_dispatch_request
    return self.finalize_request(rv)
  File "F:\Youtube Do\venv\lib\site-packages\flask\app.py",line 1970,in finalize_request
    response = self.process_response(response)
  File "F:\Youtube Do\venv\lib\site-packages\flask\app.py",line 2269,in process_response
    self.session_interface.save_session(self,ctx.session,response)
  File "F:\Youtube Do\venv\lib\site-packages\flask\sessions.py",line 378,in save_session
    val = self.get_signing_serializer(app).dumps(dict(session))
  File "F:\Youtube Do\venv\lib\site-packages\itsdangerous\serializer.py",line 166,in dumps
    payload = want_bytes(self.dump_payload(obj))
  File "F:\Youtube Do\venv\lib\site-packages\itsdangerous\url_safe.py",line 42,in dump_payload
    json = super(URLSafeSerializerMixin,self).dump_payload(obj)
  File "F:\Youtube Do\venv\lib\site-packages\itsdangerous\serializer.py",line 133,in dump_payload
    return want_bytes(self.serializer.dumps(obj,**self.serializer_kwargs))
  File "F:\Youtube Do\venv\lib\site-packages\flask\json\tag.py",line 305,in dumps
    return dumps(self.tag(value),separators=(",",":"))
  File "F:\Youtube Do\venv\lib\site-packages\flask\json\__init__.py",line 211,in dumps
    rv = _json.dumps(obj,**kwargs)
  File "c:\users\sohel\appdata\local\programs\python\python37\lib\json\__init__.py",line 238,in dumps
    **kw).encode(obj)
  File "c:\users\sohel\appdata\local\programs\python\python37\lib\json\encoder.py",line 199,in encode
    chunks = self.iterencode(o,_one_shot=True)
  File "c:\users\sohel\appdata\local\programs\python\python37\lib\json\encoder.py",line 257,in iterencode
    return _iterencode(o,0)
  File "F:\Youtube Do\venv\lib\site-packages\flask\json\__init__.py",line 100,in default
    return _json.JSONEncoder.default(self,o)
  File "c:\users\sohel\appdata\local\programs\python\python37\lib\json\encoder.py",line 179,in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type type is not JSON serializable

YoutubeDownload.py


from pytube import YouTube
import requests

class YoutubeVideo():
    def __init__(self,url):
        self.url = url
        self.Video = YouTube(url)
        self.streams = self.Video.streams

    def convert_bytes(self,size):
        """
        Returns size in KB/MD ...
        Takes 1 argument:
            size -int: Bytes
        """
        for i in ['bytes','KB','MB','GB','TB']:
            if size < 1024.0:
                return "%3.1f %s" % (size,i)
            size /= 1024.0

        return size

    def removeDuplicateStreams(self,streams):
        videoStreamQuality = []
        videoStreamPosition = []
        videoNewStreams = []
        audioStreamSize = []
        audioStreamPosition = []
        newAudioStream = []
        
        for i in range(len(streams)):
            if "video" in str(streams[i][3]):
                if not "None" in str(streams[i][1]):
                   if not "webm" in str(streams[i][3]):
                    if not streams[i][1] in videoStreamQuality:
                        videoStreamQuality.append(streams[i][1])
                        videoStreamPosition.append(i)
            elif "audio" in str(streams[i][3]):
                if not streams[i][2] in audioStreamSize:
                    audioStreamSize.append(streams[i][2])
                    audioStreamPosition.append(i)
                
        for i in range(len(videoStreamPosition)):
            videoNewStreams.append(streams[videoStreamPosition[i]])
            videoNewStreams.sort(key=lambda tup: tup[1])
            
        for i in range(len(audioStreamPosition)):
            audioStream = streams[audioStreamPosition[i]]
            if str(audioStream[1]) == "None":
                lst = list(audioStream)
                lst[1] = "Audio"
                audioStream = tuple(lst)
            newAudioStream.append(audioStream)
        return videoNewStreams + newAudioStream

    def get_origianl_streams(self):
        """"
        Returns list of original streams directly from pytube
        """
        return self.streams


    def get_streams(self):
        """
        Returns array of streams with 
        stream_id,stream_resolution,stream_filesize,stream_mime_type
        """
        newStream = []
        for i in range(len(self.streams)):
            # if not "/webm" in str(self.streams[i].mime_type):
            listStream = (i,self.streams[i].resolution,self.convert_bytes(self.streams[i].filesize_approx),self.streams[i].mime_type)
            newStream.append(listStream)
        return self.removeDuplicateStreams(newStream)

    def download(self,stream_id,file_path = None):
        """
        Dowloads the video:
        Takes 2 arguments:
            stream_id - int: id of stream (found in get_streams())
            file_path - str: (Optional) Path where file is to be downloaded,default is working dir!
        """
        stream_id = self.get_streams()[0][0]
        self.Video.streams[stream_id].download(file_path)

    def get_details(self):
        """
        Returns details in tuple
        (thumbnailUrl,title,authorName,url) 
        """
        title = self.Video.title
        authorName = self.Video.author
        thumbnailUrl = self.Video.thumbnail_url
        return (thumbnailUrl,self.url)

    def download_progress(self,func):
        """
        Rreturns functional arguments:
        chunk which also conatain filesize
        filehandle,file_size
        """
        self.Video.register_on_progress_callback(func)
    
    def download_complete(self,func):
        """
        Return functional argument:
        filepath;
        """
        self.Video.register_on_complete_callback(func)

if __name__ == "__main__":
    url = "https://youtu.be/6kwrsQLQnhA"
    url = "https://www.youtube.com/watch?v=GwgXoPBt0dM"
    yt = YoutubeVideo(url)
    print(yt.get_origianl_streams())
    print(yt.get_details())
    print(yt.get_streams())
    # yt.download(2)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-