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

基于Flask的带内置视频播放器网站:用户使用时长限制方案咨询

Answer

Great question! Your initial idea of adding a credits_minutes field to the user profile is solid—it’s the foundation for most time-based access control systems. Below’s a step-by-step breakdown of how to implement this effectively in your Flask app, along with safeguards to prevent abuse.

Core Approach: Track & Deduct Playback Minutes

The core flow will be:

  1. Each user has a credits_minutes value stored in their database record (e.g., 60 for 1 hour of access).
  2. When a user watches a video, track the actual time they spend playing it (not just the video duration—since they might pause/skip).
  3. Deduct the elapsed time from their credits_minutes in real-time or at intervals.
  4. Block video access once credits_minutes drops to 0 (or below).

Key Implementation Steps

1. Update Your User Model

First, add the credits_minutes field to your User model (assuming you’re using SQLAlchemy, a common choice with Flask):

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password_hash = db.Column(db.String(120), nullable=False)
    credits_minutes = db.Column(db.Integer, default=0)  # Set default to 0, update on signup/purchase

2. Track Playback Time (Frontend + Backend)

You can’t rely solely on the frontend to report playback time—users could tamper with it. Instead, use a combination of frontend tracking and backend validation:

Frontend (JavaScript)

Use the HTML5 video element’s events to send periodic updates to your Flask backend. For example, send a request every 30 seconds with the elapsed play time:

const video = document.getElementById('video-player');
let startTime = null;
let lastReportedTime = 0;

video.addEventListener('play', () => {
    startTime = Date.now();
    setInterval(() => {
        if (!video.paused) {
            const elapsedSeconds = Math.floor((Date.now() - startTime) / 1000) - lastReportedTime;
            if (elapsedSeconds >= 30) {  // Send update every 30 seconds
                fetch('/api/deduct-credits', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ seconds: elapsedSeconds })
                })
                .then(response => response.json())
                .then(data => {
                    if (data.remaining <= 0) {
                        video.pause();
                        alert('Your access credits have expired.');
                    }
                    lastReportedTime += elapsedSeconds;
                });
            }
        }
    }, 1000);
});

Backend (Flask Route)

Create a protected route to handle credit deductions. Validate the user is logged in, then update their credits_minutes:

from flask import request, jsonify, login_required
from flask_login import current_user

@app.route('/api/deduct-credits', methods=['POST'])
@login_required
def deduct_credits():
    data = request.get_json()
    seconds_used = data.get('seconds', 0)
    if seconds_used <= 0:
        return jsonify({'error': 'Invalid time value'}), 400
    
    # Convert seconds to minutes (round up to avoid giving free time)
    minutes_used = (seconds_used + 59) // 60
    
    # Update user credits (ensure we don't go negative)
    current_user.credits_minutes = max(current_user.credits_minutes - minutes_used, 0)
    db.session.commit()
    
    return jsonify({
        'remaining': current_user.credits_minutes,
        'used': minutes_used
    })

3. Enforce Access Restrictions

Before allowing a user to load a video, check their remaining credits in the route that serves the video page or video file:

@app.route('/video/<int:video_id>')
@login_required
def view_video(video_id):
    if current_user.credits_minutes <= 0:
        return "Your access credits have expired. Please purchase more to continue.", 403
    
    # Fetch video details and render the page
    video = Video.query.get_or_404(video_id)
    return render_template('video.html', video=video)

Bonus Tips to Prevent Abuse & Improve UX

  • Server-Side Validation: Never trust frontend reports entirely. Store the start time on the server when the user begins playing, then calculate elapsed time when they stop or send updates to cross-check.
  • Handle Pauses/Stops: Add event listeners for pause and ended events to send a final update with the total elapsed time.
  • Expire Credits Over Time: If credits have an expiration date, add an credits_expiry_date field to the User model and check it alongside credits_minutes.
  • Show Remaining Time: Display the user’s remaining credits in the navbar or video player so they know how much time they have left.
  • Batch Deductions: Instead of deducting every second, batch updates every 30-60 seconds to reduce server load.

Alternative: Session-Based Time Tracking

If you don’t need persistent credits (e.g., limited access per session), you could track time spent in the user’s session. But your initial credits_minutes approach is better for long-term access control.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:37:44