极简短视频查看、删除应用
本地短视频服务器
背景:我的NAS中存放了很多短视频,多到很多没看过,于是写了这个程序来随机查看并删除短视频
运行:
安装依赖后运行main.py
直接使用docker:
docker pull realwang/short_video
docker run -d -p 3000:3000 -v /path/to/your/video:/app/video realwang/short_video
功能
- 扫描本地视频和图片,并在网页上显示
- 在网页上 点赞和删除文件
- 上下滑动来切换文件
- 媒体文件放在video目录下
- 本地数据库
代码由4个文件组成
1.数据库操作
# database.pyimport sqlite3def init_db():conn = sqlite3.connect('media.db')c = conn.cursor()c.execute('''CREATE TABLE IF NOT EXISTS media(id INTEGER PRIMARY KEY, name TEXT, path TEXT, views INTEGER DEFAULT 0, likes INTEGER DEFAULT 0)''')conn.commit()conn.close()def add_media(name, path):try:conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("INSERT INTO media (name, path) VALUES (?, ?)", (name, path))conn.commit()conn.close()return Trueexcept sqlite3.IntegrityError:# 处理重复键错误等数据库约束错误return Falseexcept Exception as e:print(f"Error inserting {name} into database: {str(e)}")return Falsedef update_views(media_id):conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("UPDATE media SET views = views + 1 WHERE id = ?", (media_id,))conn.commit()conn.close()def update_likes(media_id):conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("UPDATE media SET likes = likes + 1 WHERE id = ?", (media_id,))conn.commit()conn.close()def delete_media(media_id):conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("DELETE FROM media WHERE id = ?", (media_id,))conn.commit()conn.close()def get_random_media():conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("SELECT id, name, path FROM media ORDER BY RANDOM() LIMIT 1")media = c.fetchone()conn.close()return media
2.文件扫描
#scanner.py
import os
import time
import sqlite3
from database import init_db, add_mediadef scan_directory(directory='video'):init_db()print(f"扫描目录: {directory}")for root, dirs, files in os.walk(directory):for file in files:if file.endswith(('.mp4', '.jpg', '.png', '.gif')):path = os.path.join(root, file)print(f"发现文件: {file} 路径: {path}")try:result = add_media(file, path)#print(f"add_media 返回: {result}") # Debug: Print the return valueif result:print(f"插入 {file} 到数据库")else:print(f"插入 {file} 到数据库失败")except Exception as e:print(f"由于异常无法插入 {file} 到数据库: {str(e)}")def incremental_scan(directory='video'):scanned_files = set()conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("SELECT path FROM media")for row in c.fetchall():scanned_files.add(row[0])conn.close()print("开始增量扫描...")for root, dirs, files in os.walk(directory):for file in files:if file.endswith(('.mp4', '.jpg', '.png', '.gif')):path = os.path.join(root, file)if path not in scanned_files:print(f"发现新文件: {file} 路径: {path}")try:result = add_media(file, path)print(f"add_media 返回: {result}") # Debug: Print the return valueif result:print(f"插入 {file} 到数据库")else:print(f"插入 {file} 到数据库失败")except Exception as e:print(f"由于异常无法插入 {file} 到数据库: {str(e)}")else:print(f"跳过已存在文件: {file}")if __name__ == '__main__':init_db()while True:incremental_scan()time.sleep(3600) # 每小时扫描一次
3.web服务
#app.pyfrom flask import Flask, render_template, request, send_file, jsonify, send_from_directory
import os
import sqlite3
import random # 导入 random 模块
from database import init_db, update_views, update_likes, delete_media, get_random_mediaapp = Flask(__name__)def is_video_file(path):return path.lower().endswith('.mp4')def is_image_file(path):return path.lower().endswith('.jpg') or path.lower().endswith('.jpeg') or path.lower().endswith('.png')def get_random_media():conn = sqlite3.connect('media.db')c = conn.cursor()rand_num = random.random() # Generate a random number between 0 and 1if rand_num < 0.9:c.execute("SELECT id, name, path FROM media WHERE path LIKE '%.mp4' ORDER BY RANDOM() LIMIT 1;")else:c.execute("SELECT id, name, path FROM media WHERE path LIKE '%.jpg' OR path LIKE '%.jpeg' OR path LIKE '%.png' ORDER BY RANDOM() LIMIT 1;")media = c.fetchone()conn.close()return media@app.route('/')
def index():media = get_random_media()if media:media_id, name, path = mediaupdate_views(media_id)conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("SELECT likes FROM media WHERE id = ?", (media_id,))likes = c.fetchone()[0]conn.close()return render_template('index.html', media_id=media_id, name=name, path=path, likes=likes,is_video=is_video_file(path), is_image=is_image_file(path))return "No media found"@app.route('/media/<path:filename>')
def media(filename):return send_from_directory(directory=os.path.dirname(filename), path=os.path.basename(filename))@app.route('/like/<int:media_id>', methods=['POST'])
def like(media_id):update_likes(media_id)conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("SELECT likes FROM media WHERE id = ?", (media_id,))likes = c.fetchone()[0]conn.close()return jsonify(success=True, likes=likes)@app.route('/delete/<int:media_id>', methods=['POST'])
def delete(media_id):conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("SELECT path FROM media WHERE id = ?", (media_id,))path = c.fetchone()[0]conn.close()if os.path.exists(path):os.remove(path)delete_media(media_id)return jsonify(success=True)@app.route('/download/<int:media_id>')
def download(media_id):conn = sqlite3.connect('media.db')c = conn.cursor()c.execute("SELECT path FROM media WHERE id = ?", (media_id,))path = c.fetchone()[0]conn.close()return send_file(path, as_attachment=True)if __name__ == '__main__':init_db() # 确保数据库和表被初始化app.run(host='0.0.0.0', port=3000, debug=True)
4.启动器
import os
import threading
import time# 定义运行scanner.py的函数
def run_scanner():# 清空并创建scanner.log文件with open('log/scanner.log', 'wb') as f:passos.system('python scanner.py > log/scanner.log 2>&1')# 定义运行app.py的函数
def run_app():# 清空并创建app.log文件with open('log/app.log', 'wb') as f:passos.system('python app.py > log/app.log 2>&1')if __name__ == '__main__':# 创建log子目录os.makedirs('log', exist_ok=True)# 创建并启动线程运行scanner.pyscanner_thread = threading.Thread(target=run_scanner)scanner_thread.start()# 等待3秒钟time.sleep(3)# 创建并启动线程运行app.pyapp_thread = threading.Thread(target=run_app)app_thread.start()相关文章:
极简短视频查看、删除应用
本地短视频服务器 背景:我的NAS中存放了很多短视频,多到很多没看过,于是写了这个程序来随机查看并删除短视频 运行: 安装依赖后运行main.py 直接使用docker: docker pull realwang/short_video docker run -d -p 3000:…...
【秋招刷题打卡】Day01-自定义排序
Day01-自定排序 前言 给大家推荐一下咱们的 陪伴打卡小屋 知识星球啦,详细介绍 >笔试刷题陪伴小屋-打卡赢价值丰厚奖励 < ⏰小屋将在每日上午发放打卡题目,包括: 一道该算法的模版题 (主要以力扣,牛客,acwin…...
API低代码平台介绍6-数据库记录删除功能
数据库记录删除功能 在前续文章中我们介绍了如何插入和修改数据库记录,本篇文章会沿用之前的测试数据,介绍如何使用ADI平台定义一个删除目标数据库记录的接口,包括 单主键单表删除、复合主键单表删除、多表删除(整合前两者&#x…...
计算机基础之:硬件系统的性能评估标准
服务器时钟的性能通常涉及多个方面,主要包括准确性、稳定性、以及对系统性能的影响。以下是一些关键指标和衡量方法: 准确性: 时间偏移:测量服务器时钟与一个可靠时间源(如GPS时间、原子钟或NTP服务器)之间…...
高互动UI设计揭秘:动画效果如何提升用户体验
动画,由于其酷的视觉冲击,往往会产生极好的用户体验。UI设计中的动态效果可以使用户界面看起来更酷,特别是界面的功能动画,是UX设计的重要组成部分,不容忽视。为什么UI设计的动态效果如此重要?接下来&#…...
探索Java异常处理的奥秘:源码解析与高级实践
1. 引言 在Java编程的广阔天地中,异常处理是确保程序健壮性、稳定性和可维护性的重要基石。对于Java工程师而言,深入理解Java异常处理的机制,并能够在实践中灵活运用,是迈向卓越的重要一步。 2. 基本概念 在Java中,异常(Exception)是程序执行期间出现的不正常或错误情况…...
深入了解python函数与函数内存使用
函数的定义 函数作为代码复用的基本单元,可以帮助我们组织代码、减少重复、提高可读性和可维护性。 在 Python 中,函数本质上是对象,可以赋值给变量、存储在数据结构中、作为参数传递和返回。 函数与内存 函数的加载和调用过程中ÿ…...
Java面试----MySQL面试题
1.索引有哪些优缺点? MySQL索引作为一种提升数据库查询效率的重要机制,具有以下主要优点和缺点: 优点: 提高查询速度: 索引能够显著加速数据的检索过程,类似于书籍的目录,让数据库引擎能够快速…...
python从入门到精通2:缩进
在Python中,缩进(Indentation)是一个非常重要的语法元素,它用于表示代码块的结构。与其他许多编程语言使用大括号 {} 来定义代码块不同,Python使用缩进来确定代码块的开始和结束。这种简洁的语法使得Python代码更加清晰…...
了解CDN:提升网络性能和安全性的利器
在当今的数字时代,网站性能和安全性是每一个网站管理员必须关注的核心问题。内容分发网络(CDN,Content Delivery Network)作为解决这一问题的重要工具,逐渐成为主流。本文将详细介绍CDN的定义、作用及其工作原理&#…...
ChatGPT的工作原理
ChatGPT的工作原理可以详细分为以下几个步骤,下面将结合相关信息进行清晰、详细的介绍: 数据收集: ChatGPT首先会从大量的文本数据中收集信息,这些数据可能包括网页、新闻、书籍等多样化的来源。它还会特别关注和分析网络上的热点…...
基于DPU的云原生裸金属服务快速部署及存储解决方案
1. 背景介绍 1.1. 业务背景 在云原生技术迅速发展的当下,容器技术因其轻量级、可移植性和快速部署的特性而成为应用部署的主流选择,但裸金属服务器依然有其独特的价值和应用场景,是云原生架构中不可或缺的一部分。 裸金属服务器是一种高级…...
论文学习_Large Language Models Based Fuzzing Techniques: A Survey
论文名称发表时间发表期刊期刊等级研究单位Large Language Models Based Fuzzing Techniques: A Survey 2024年arXiv-悉尼大学 0.摘要 研究背景在软件发挥举足轻重作用的现代社会,软件安全和漏洞分析对软件开发至关重要,模糊测试作为一种高效的软件测试方法,并广泛应用于各个…...
响应式德米拉数字内容交易系统素材下载站模板
★模板说明★ 该数字交易系统设计非常完美,两种响应式模式,可打开边栏模式和盒子模式;八种网站颜色,四种风格颜色可供用户自行选择,还可在网站选背景图片;完美的分成系统、充值功能、个人中心等等都以html…...
数据库开发-MySQL
前言 首先来了解一下什么是数据库。 数据库:英文为 DataBase,简称DB,它是存储和管理数据的仓库。 像我们日常访问的电商网站京东,企业内部的管理系统OA、ERP、CRM这类的系统,以及大家每天都会刷的头条、抖音类的app…...
香港大带宽服务器高性能配置选择灵活
香港大带宽服务器是指在香港数据中心托管的,配备了高速网络连接的服务器。这些服务器通常用于需要大量数据传输和快速响应时间的应用,如视频流媒体、在线游戏、远程工作和大规模数据处理任务。具体分析如下,rak部落为您整理发布。 1. **内存配…...
Oracle中生僻汉字的解决办法
在Oracle数据库中处理生僻汉字时,主要面临的问题是某些字符集可能无法完全支持所有的汉字,特别是生僻字。以下是一些解决Oracle中生僻汉字问题的办法: 检查当前字符集: 使用SELECT USERENV(language) FROM dual;命令来查看当前数…...
在Kotlin中,`field`关键字是一个特殊的标识符,用于在属性的自定义getter和setter中访问backing field(存储属性值的实际字段)
在Kotlin中,field关键字是一个特殊的标识符,用于在属性的自定义getter和setter中访问backing field(存储属性值的实际字段)。Kotlin属性默认提供getter和setter方法,但当你需要自定义它们的行为时,可以使用…...
如何在 MySQL 中创建和使用事务?
目录 1. 环境准备 2. 创建事务 3. 事务执行 4. 事务撤消 5. 总结 事务是数据库区别于文件系统的重要特征之一,当我们有了事务就会让数据库始终保持一致,同时我们还能通过事务机制恢复到某个时间点,这样可以保证已提交到数据库的修改不会…...
Python数据分析-对驾驶安全数据进行了预测
一、研究背景和意义 随着汽车保有量的不断增加,交通事故已成为全球范围内的重大公共安全问题。每年因交通事故造成的人员伤亡和财产损失给社会带来了巨大的负担。为了提高驾驶安全,减少交通事故的发生,许多研究致力于探索影响驾驶安全的因素…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
