蜗牛博客
记录生活中的点点滴滴

终于把你给定住了

videod.jpg
videod.jpg

整体功能总结

这段代码实现了一个完整的视频播放页面,核心功能包括:

  • 动态调用后台配置的视频 API,支持灵活更换视频源;
  • 视频播放、切换、连续播放等基础控制;
  • 加载状态提示与错误自动重试,提升用户体验;
  • 自适应不同设备(桌面 / 移动端)的响应式布局;
  • 视频资源保护(禁用下载、右键菜单、添加水印);
  • 与 Typecho 博客系统无缝集成,支持动态加载评论模块和模板组件。
  • 通过 CSS+HTML+PHP+JS 的配合,实现了 “美观、易用、适配、安全” 的视频播放体验。
使用场景与扩展

若需要更换水印内容,只需修改div标签内的文字(如改为网站域名、品牌名等);

  • 如需更换位置,可调整top/right属性(例如left:10px改为左上角);
  • 若想使用图片水印,可将div标签替换为img标签,并调整样式(如background-image),保持pointer-events: none和层级设置即可。

总体而言,该水印设计在版权保护和用户体验之间做了平衡,既起到了标识作用,又不会过度干扰视频观看。

<style>
    /* 添加媒体查询适配移动端 */
    @media (max-width: 768px) {
        .sm-mainContent {
            flex-direction: column;
        }
        
        #player-container {
            transition: none; /* 移动端禁用过渡动画避免错位 */
        }
        
        .video-wrapper {
            width: 100%; /* 移动端全宽度 */
            max-width: none;
            margin-bottom: 20px;
        }
        
        #buttons {
            flex-direction: column;
            align-items: center;
        }
        
        #switch, #next1 {
            width: 90%;
            max-width: 300px;
            margin: 6px 0;
        }
        
        /* 移动端横屏模式 */
        .video-wrapper.landscape-mode {
            width: 100%;
            max-width: none;
        }
    }

    /* 原有样式优化 */
    #switch,#next1{
        background: linear-gradient(135deg, #7b68ee 0%, #4895ef 100%);
        color:#fff;
        line-height:40px;
        text-align:center;
        width:100px;
        border:none;
        margin:0 6px;
        border-radius:6px;
        font-weight:bold;
        cursor: pointer;
        transition: all 0.3s ease;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    }
    
    #switch:hover,#next1:hover{
        background: linear-gradient(135deg, #6a5acd 0%, #3d85c6 100%);
        transform: scale(1.05);
        box-shadow: 0 4px 8px rgba(0,0,0,0.15);
    }
    
    #switch:active,#next1:active{
        transform: scale(0.98);
    }
    
    .widget{
        margin: 20px 0;
    }
    
    .video-wrapper {
        width: 70%;
        margin: 0 auto;
        position: relative;
        max-width: 600px;
        min-height: 300px;
        transition: all 0.3s ease;
    }
    
    /* 横屏模式下的容器样式 */
    .video-wrapper.landscape-mode {
        width: 100%;
        max-width: none;
    }
    
    #player-container {
        width: 100%;
        position: relative;
        background-color: #000;
        overflow: hidden;
        aspect-ratio: 9/16; /* 默认竖屏比例 */
        transition: all 0.3s ease;
    }
    
    /* 横屏比例类 */
    #player-container.landscape {
        aspect-ratio: 16/9;
    }
    
    #player {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: contain;
    }
    
    /* 优化后的加载提示 */
    .video-loading {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0,0,0,0.7);
        z-index: 10;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: flex-start; /* 顶部对齐 */
        padding-top: 40%; /* 避免遮挡播放按钮 */
    }
    
    .video-loading-text {
        color: white;
        font-size: 16px;
        margin-top: 15px;
        text-align: center;
        max-width: 80%;
    }
    
    .loader {
        width: 40px;
        height: 40px;
        border: 4px solid rgba(255,255,255,0.2);
        border-top: 4px solid #7b68ee;
        border-radius: 50%;
        animation: spin 1s linear infinite;
    }
    
    @keyframes spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
    }
    
    .video-watermark {
        position: absolute;
        top: 10px;
        right: 10px;
        color: rgba(255, 255, 255, 0.3);
        font-size: 18px;
        font-weight: bold;
        pointer-events: none;
        z-index: 5;
        text-shadow: 0 0 2px rgba(0,0,0,0.3);
    }
   
    .video-controls {
        text-align: center;
        margin-top: 10px;
        padding: 10px 0;
    }
    
    /* 确保播放按钮可点击 */
    #player::-webkit-media-controls-play-button {
        z-index: 15;
    }
</style>

<div class="sm-mainContent">
    <div class="sm-innermainContent">
        <section>
            <article>
                <section class="widget xm-margin-top20 xm-list-wai">
                    <ul class="widget-list">
                        <div class="video-wrapper" id="videoWrapper">
                            <div id="player-container">
                                <div class="video-loading" id="videoLoading">
                                    <div class="loader"></div>
                                    <div class="video-loading-text">视频加载中,请稍候...</div>
                                </div>
                                <!-- 替换为动态视频路径 -->
                                <div id="player-wrapper">
                                    <div class="video-watermark">蜗牛视频</div>
                                    <video id="player" src="<?php $this->options->video(); ?>" controls="controls"
                                           controlsList="nodownload" oncontextmenu="return false"></video>
                                </div>
                            </div>
                            
                            <div class="video-controls">
                                <section id="buttons">
                                    <button id="switch">连续: 开</button>
                                    <button id="next1">换一个</button>
                                </section>
                            </div>
                        </div>
                    </ul>
                </section>
            </article>
        </section>
        
        <?php 
        // 保留原有的评论模块调用
        if($this->options->xmmokuai == 'mkb'){
            $this->need('commentsa.php'); 
        }elseif($this->options->xmmokuai == 'mkc'){
            $this->need('commentsb.php'); 
        }else{
            $this->need('comments.php'); 
        }
        ?>
    </div>
</div>

<?php $this->need('sidebar.php'); ?>
<?php $this->need('footer.php'); ?>

<script>
    (function (window, document) {
        if (top != self) {
            window.top.location.replace(self.location.href);
        }
        
        var get = function (id) {
            return document.getElementById(id);
        }
        
        var bind = function (element, event, callback) {
            return element.addEventListener(event, callback);
        }
        
        var auto = true;
        var player = get('player');
        var loadingIndicator = get('videoLoading');
        var playerContainer = get('player-container');
        var videoWrapper = get('videoWrapper');
        
        var showLoading = function() {
            loadingIndicator.style.display = 'flex';
            
            // 根据播放器大小调整提示位置
            var playerHeight = playerContainer.offsetHeight;
            var topPosition = Math.min(playerHeight * 0.4, 200); // 最高不超过200px
            
            // 设置加载提示位置
            loadingIndicator.style.paddingTop = topPosition + 'px';
        };
        
        var hideLoading = function() {
            loadingIndicator.style.display = 'none';
            loadingIndicator.style.paddingTop = '40%'; // 恢复默认值
        };
        
        // 优化后的比例调整函数
        var adjustPlayerRatio = function() {
            var videoWidth = player.videoWidth;
            var videoHeight = player.videoHeight;
            
            if (videoWidth && videoHeight) {
                var aspectRatio = videoWidth / videoHeight;
                
                // 移除所有比例类
                playerContainer.classList.remove('landscape');
                videoWrapper.classList.remove('landscape-mode');
                
                // 判断横屏视频
                if (aspectRatio > 1) {
                    playerContainer.classList.add('landscape');
                    videoWrapper.classList.add('landscape-mode');
                }
            }
        };
        
        var randomm = function () {
            showLoading();
            player.pause();
            // 动态获取视频API路径并添加随机参数防止缓存
            var baseUrl = '<?php $this->options->video(); ?>';
            var newSrc = baseUrl + (baseUrl.indexOf('?') > -1 ? '&' : '?') + '_t=' + Math.random();
            player.src = newSrc;
            
            // 重置容器比例
            playerContainer.classList.remove('landscape');
            videoWrapper.classList.remove('landscape-mode');
            
            player.play().then(function() {
                // 延迟调整比例确保元数据加载
                setTimeout(adjustPlayerRatio, 500);
                hideLoading();
            }).catch(function() {
                setTimeout(hideLoading, 500);
            });
        };
        
        bind(get('next1'), 'click', randomm);
        
        bind(player, 'error', function () {
            hideLoading();
            setTimeout(randomm, 500);
        });
        
        bind(player, 'loadedmetadata', function() {
            adjustPlayerRatio();
        });
        
        bind(player, 'canplay', function() {
            hideLoading();
        });
        
        bind(get('switch'), 'click', function () {
            auto = !auto;
            this.innerText = '连续: ' + (auto ? '开' : '关');
        });
        
        bind(player, 'ended', function () {
            if (auto) {
                randomm();
            }
        });
        
        // 初始加载
        window.addEventListener('load', function() {
            // 初始化比例
            setTimeout(adjustPlayerRatio, 1000);
            
            // 初始显示加载提示
            showLoading();
            
            // 如果视频已经可以播放,则隐藏加载提示
            if (player.readyState >= 3) {
                setTimeout(hideLoading, 500);
            }
        });
        
        // 监听窗口大小变化调整加载提示位置
        window.addEventListener('resize', function() {
            if (loadingIndicator.style.display === 'flex') {
                showLoading();
            }
        });
    })(window, document);
</script>

一直琢磨着给 “小姐姐视频” 页面弄个固定效果,这样每次刷视频时页面就不会来回晃动,可惜这事儿搁了好久都没搞定。今天有空问了下 AI,跟豆包大模型聊了几次,它还真做出了我想要的效果,太厉害了,必须感谢!有了 AI,像我这样的新手也能玩得很顺手,真不错!最让我开心的是,播放器能根据视频的实际比例,自动在 9:16 和 16:9 之间切换,这操作简直帅呆了!!!

前去观看:https://www.wnblog.com/niumei.html

来自豆包 doubao.com
文章声明: 部分内容可能来源于公共网络,仅供学习交流,如有侵权,请联系博主进行核实删除。
标签:AI DIY 播放器
评论: 17 | 查看: 534

  1. 全局变量的头像
    全局变量精英

    美女图是要上线了吗、期待。

    6天前 · 湖南省岳阳市 · 回复
    1. 蜗牛不是牛的头像
      @全局变量

      没呢没呢,期待大佬你能整一个哈。尬笑

      6天前 · 湖南省怀化市 · 回复
  2. 有趣云邮的头像
    有趣云邮专家

    看了一个视频又一个视频,差点陷入进去了(好东西值得折腾)哈哈哈

    6天前 · 火星地区 · 回复
    1. 蜗牛不是牛的头像
      @有趣云邮

      这上千小视频中我放了一个彩蛋,不知道何位大佬能刷到。有点后怕了。

      6天前 · 湖南省怀化市 · 回复
      1. 有趣云邮的头像
        有趣云邮专家
        @蜗牛不是牛

        还有彩蛋啊?有意思咯哈哈

        6天前 · 火星地区 · 回复
  3. 旺东的头像
    旺东专家

    精神食粮嘛!据说80%男人的博客都有小姐姐视频

    6天前 · 甘肃省兰州市 · 回复
    1. 蜗牛不是牛的头像
      @旺东

      看来我和旺东大佬是在同一正营,有空还得在多挖掘点新资源!

      6天前 · 湖南省怀化市 · 回复
      1. 旺东的头像
        旺东专家
        @蜗牛不是牛

        之前还有18+的api 现在基本全封完了!

        6天前 · 甘肃省兰州市 · 回复
        1. 蜗牛不是牛的头像
          @旺东

          怪只可惜的,我都没看过。早点认识旺东大佬就好了。

          6天前 · 湖南省怀化市 · 回复
          1. 旺东的头像
            旺东专家
            @蜗牛不是牛

            福利时代一去不回了!

            6天前 · 甘肃省兰州市 · 回复
  4. 彬红茶的头像
    彬红茶精英

    为了一个美女,也是拼了个命傻笑

    6天前 · 广东省 · 回复
    1. 蜗牛不是牛的头像
      @彬红茶

      小偷 想要的东西花钱也想搞到,虽然没啥意义,不过这过程可以带来快感,嘿嘿~

      6天前 · 湖南省怀化市 · 回复
  5. 阿航的头像
    阿航大师

    太有精力折腾了皮哥

    6天前 · 广东省东莞市 · 回复
    1. 蜗牛不是牛的头像
      @阿航

      哈哈,就这点爱好了打发时间,没条件和你一样可以外出旅游!尴尬了~

      6天前 · 湖南省怀化市 · 回复
      1. 阿航的头像
        阿航大师
        @蜗牛不是牛

        皮哥又低调了加班

        6天前 · 广东省东莞市 · 回复
        1. 蜗牛不是牛的头像
          @阿航

          过个把月要广东中山三日游,要不要约下江边钓鱼。去年我可钓到不少大货。

          6天前 · 湖南省怀化市 · 回复
          1. 阿航的头像
            阿航大师
            @蜗牛不是牛

            我要看到时候有没时间过去呢

            6天前 · 广东省东莞市 · 回复
发表评论
隐私评论
©2024-2025 蜗牛博客 map
湘ICP备2024058534号-2 茶ICP备2025088888号