【问题标题】:Videos in subfolders of static not working静态子文件夹中的视频不起作用
【发布时间】:2020-02-13 21:49:28
【问题描述】:

我找到了这个sn-p的代码:

from flask import Flask
import flask
from os import listdir
import os.path
import pathlib
import ntpath


app = Flask(__name__)
@app.route('/', defaults={'req_path': ''})
@app.route('/<path:req_path>')
def dir_listing(req_path):
    BASE_DIR = 'D:/Users/xxx/projects/project1/static'

    # Joining the base and the requested path
    abs_path = os.path.join(BASE_DIR, req_path)

    # Return 404 if path doesn't exist
    if not os.path.exists(abs_path):
        return flask.abort(404)

    # Check if path is a file and serve
    if os.path.isfile(abs_path):
        return flask.send_file(abs_path)

    # Show directory contents
    files = os.listdir(abs_path)
    for i, f in enumerate(files):
        files[i] = os.path.join(req_path, f).replace('\\', '/')
    return flask.render_template('files.html', files=files)


if __name__ == '__main__':
    app.run(host='10.13.0.33', port=80)

连同相应的index.html:

<ul>
    {% for file in files %}
        <li><a href="{{ file }}">{{ file }}</a></li>
    {% endfor %}
</ul>

在您到达 SecondFolder 之前,它会按预期工作!
呈现的 html 看起来不错:

<ul>
    <li><a href="FirstFolder/SecondFolder/file3.mp4">FirstFolder/SecondFolder/file3.mp4</a></li>
    <li><a href="FirstFolder/SecondFolder/ThirdFolder">FirstFolder/SecondFolder/ThirdFolder</a></li>
</ul>

但是,当我将鼠标悬停在链接上时,我得到了这个(注意第一个文件夹是重复的!): http://10.13.0.33/FirstFolder/FirstFolder/SecondFolder/ThirdFolder

原帖: 我正在尝试在嵌套文件夹中显示视频链接。每个文件夹中有很多文件(多达 30 个),所以我不想一次下载或播放所有文件。这个想法是让用户看到他们想要查看的内容并单击播放按钮。

目前正在使用 PyCharm 在 Windows 10 上开发/测试。

顶级(主页)页面和下一个文件夹深度按预期运行。当我选择下一个深度文件夹时,视频被标记为“无效来源”

深度有限制吗?

这是我的代码:

from flask import Flask
from os import listdir
import os.path
import pathlib
import ntpath


def remove_top_folder(path):
    path_to_file = pathlib.Path(path)
    path_to_file = path_to_file.relative_to(*path_to_file.parts[:1])
    return str(path_to_file).replace('\\', '/')


def get_folders(folder):
    if folder is not None and os.path.isdir(folder):
        folders = []
        for f in listdir(folder):
            path_to_folder = os.path.join(folder, f).replace('\\', '/')
            if os.path.isdir(path_to_folder) and not f.startswith('.'):
                folders.append(remove_top_folder(path_to_folder))
        return folders
    return None


def get_videos(folder):
    if folder is not None and os.path.isdir(folder):
        videos = []
        for f in listdir(folder):
            path_to_video = os.path.join(folder, f).replace('\\', '/')
            if os.path.isfile(os.path.join(folder, f)) and not f.startswith('.') and f.endswith('.mp4'):
                videos.append(path_to_video)
        return videos
    return None


def get_stuff(folder):
    folders = get_folders(folder)
    videos = get_videos(folder)
    if folder == 'static\\' or folder == 'static/':
        rtn = ''
    else:
        rtn = '<H1>{}</H1>'.format(remove_top_folder(folder))
    if videos is not None:
        for file_name in videos:
            file_name = file_name
            rtn += '''
            <div class="container">
                <video width="320" controls preload="metadata">
                  <source src="{0}" type="video/mp4">
                </video>
            <div class="top">{1}</div>
            </div>
            '''.format(file_name, ntpath.basename(file_name))

    for folder in folders:
        rtn += '''
        <div class="container">
          <a href="{0}">{1}
        </div>
        '''.format(folder, ntpath.basename(folder))
    return rtn


app = Flask(__name__)
@app.route('/', defaults={'u_path': ''})
@app.route('/<path:u_path>')
def catch_all(u_path):
    if u_path is None:
        folder = 'static//'
    elif u_path.endswith('mp4'):
        rtn = '''
        <div class="container">
            <video width="320" controls preload="metadata">
              <source src="{0}" type="video/mp4">
            </video>
        <div class="top">{1}</div>
        </div>
        '''.format(u_path, remove_top_folder(u_path))
        return rtn
    else:
        folder = os.path.join('static', u_path).replace('\\', '/')
    stuff = get_stuff(folder)
    html = '''
        <!doctype html>
        <html>
            <body>
                <h1>{0}</h1>
            </body>
        </html>
    '''.format(stuff)
    return html


if __name__ == '__main__':
    app.run(host='10.13.0.33', port=80)

我的文件夹看起来像这样:

static
  file_1.mp4
  First_Folder
    file_2.mp4
    Second_folder
      file_3.mp4

当我访问网页时,我得到了这个:

当我点击 FirstFolder 链接时,我得到了这个:

当我点击 SecondFolder 链接时,我得到了这个:

【问题讨论】:

  • 我没有回答您的具体问题,但看起来您正在“重新发明轮子”。 Flask 有 serving static files 的便捷方式,以及在您的 html 中使用 templates
  • 感谢您的帮助(如果我遗漏了什么,我深表歉意),但我不是要下载文件,而是要在浏览器中显示它。
  • 我认为关于网站如何工作的一些误解超出了这个问题的范围。我会仔细阅读this 教程。它比您在这里尝试做的要多得多,但它有助于理解典型的 wep 应用程序的功能。
  • 尽管如此,由于某种原因,我无法在嵌套太深的文件夹中提供视频。我的问题仍然是:这是烧瓶限制吗?
  • 澄清一下,我实际上不想在访问网页时下载视频:每个文件夹中的视频太多,无法同时开始播放。这就是我在 html 中使用 preload="metadata" 标记的原因。我希望用户查看图像并决定播放哪个视频。

标签: python flask mp4


【解决方案1】:

我搞定了:

app.py:

import flask
import ntpath
import os
import socket

host_name = socket.gethostname()
if host_name == 'hostname1':
    static_folder = '/some/path/to/videos'
    ip_address = '192.xxx.xxx.xxx'
    port = 80
elif host_name == "hostname2":
    static_folder = '/another/path/to/videos'
    ip_address = '10.xxx.xxx.xxx'
    port = 8000
else:
    raise Exception('hostname is not defined!')


def remove_static_folder(path):
    path_to_file = path.replace(static_folder, '/')
    return path_to_file


def get_folders(folder):
    if folder is not None and os.path.isdir(folder):
        folders = []
        for f in os.listdir(folder):
            path_to_folder = os.path.join(folder, f).replace('\\', '/')
            if os.path.isdir(path_to_folder) and not f.startswith('.'):
                folders.append([remove_static_folder(path_to_folder), ntpath.basename(path_to_folder)])
        return folders
    return []


def get_videos(folder):
    if os.path.isdir(folder):
        print("is dir")
    if folder is not None and os.path.isdir(folder):
        videos = []
        for f in os.listdir(folder):
            if os.path.isfile(os.path.join(folder, f)) and not f.startswith('.') and f.endswith('.mp4'):
                path_to_video = os.path.join(folder, f).replace('\\', '/')
                videos.append([remove_static_folder(path_to_video), ntpath.basename(f)])
        return videos
    return []


app = flask.Flask(__name__, static_folder=static_folder,
                  static_url_path= os.path.join(os.path.sep, os.path.basename(os.path.normpath(static_folder))))


@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
    if path is None or path == "":
        folder = static_folder
    else:
        folder = os.path.join(static_folder, path).replace('\\', '/')
    videos = get_videos(folder)
    folders = get_folders(folder)
    folder = remove_static_folder(folder)
    if folder.startswith(".") or folder.startswith('/'):
        folder = folder[1:]
    return flask.render_template("index.html", folder=folder, videos=videos, folders=folders)


if __name__ == '__main__':
    if ip_address is None:
        print("hostname cannot be determined")
        exit(-1)
    app.run(host=ip_address, port=port)

index.html:

<!DOCTYPE html>
<html>

<head>
    <title>{{ folder }}</title>
</head>

<body>
    <div>
        <h1>{{ folder}} </h1>
        <ul>
            {% for video in videos %}
                <div class="container">
                    <video width="640" controls preload="metadata">
                      <source src="{{ url_for('static', filename=video[0]) }}" type="video/mp4">
                    </video>
                    <div class="top">{{ video[1] }}</div>
                </div>
            {% endfor %}
        </ul>
        <ul>
            {% for folder in folders %}
                <a href="{{ folder[0] }}">{{ folder[1] }} <br>
            {% endfor %}
        </ul>
    </div>
</body>

</html>

【讨论】:

    猜你喜欢
    • 2017-10-04
    • 2018-06-20
    • 2022-07-11
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 2012-08-16
    • 1970-01-01
    相关资源
    最近更新 更多