移动端H5音频与视频问题及解决方案

by admin on 2019年10月4日

移动端H5音频与视频问题及解决方案

2015/09/16 · HTML5 · 1
评论 ·
视频,
音频

原文出处:
Aaron的博客   

最近在研究用视频代替动画,已经初步有成果了,顺便总结下几年开发中遇到的实际问题及给出自己的解决方案

看下最后实际效果:兼容PC,iphone, 安卓5.0

解决了,手动,自动,不全屏的问题

左边视频代替了动画,然后支持背景蒙板效果,能够透出底图

右边是原视频文件

图片 1

H5 audio音频

  • 每次通过 new Audio
    一个音频对象,在IOS上可以看到会产生一个新的线程,这个很恶心

解决方案:

new Audio一个对象,通过替换不同的音频地址,达到不多开线程的目的

  • 在安卓上支持不给力

解决方案:

低版本安卓上的问题没解,一般是混合开发都是可以调底层接口处理的,比如
phonegap

  • iphone上不能自动播放

解决方案:

iphone上自动播放,是IOS设计的的时候做的一个处理,貌似是为了防止自动盗用流量吧

简单来说,需要模拟用户手动去触发才可以

所以我们需要在最开始调用这样一段代码:

这是我项目上的,我就直接扣过来了

JavaScript

//修复ios 浏览器不能自动播放音频的问题 在加载时创建新的audio
用的时候更换src即可 Xut.fix = Xut.fix||{}; if (Xut.plat.isBrowser &&
Xut.plat.isIOS) { var isAudio = false var fixaudio = function() { if
(!isAudio) { isAudio = true; Xut.fix.audio = new Audio();
document.removeEventListener(‘touchstart’, fixaudio, false); } };
document.addEventListener(‘touchstart’, fixaudio, false); }

1
2
3
4
5
6
7
8
9
10
11
12
13
//修复ios 浏览器不能自动播放音频的问题 在加载时创建新的audio 用的时候更换src即可
Xut.fix = Xut.fix||{};
if (Xut.plat.isBrowser && Xut.plat.isIOS) {
    var isAudio = false
    var fixaudio = function() {
        if (!isAudio) {
            isAudio = true;
            Xut.fix.audio = new Audio();
            document.removeEventListener(‘touchstart’, fixaudio, false);
        }
    };
    document.addEventListener(‘touchstart’, fixaudio, false);
}

假如在body上绑定这样一个代码:通过手动触发创建一个audio对象,然后保存在全局中

在使用的时候如下

JavaScript

//如果为ios browser 用Xut.fix.audio 指定src 初始化见app.js if
(Xut.fix.audio) { audio = Xut.fix.audio; audio.src = url; } else { audio
= new Audio(url); } audio.autoplay = true; audio.play();

1
2
3
4
5
6
7
8
9
10
11
//如果为ios browser 用Xut.fix.audio 指定src 初始化见app.js
if (Xut.fix.audio) {
    audio
=
Xut.fix.audio;
    audio.src = url;
} else {
    audio = new Audio(url);
}
audio.autoplay = true;
audio.play();

直接替换音频对象即可,简单来说,就是要自动就必须是用户触发创建的对象才能播

H5 video音频

视频标签可能在移动端用的很少,安卓支持太烂了,目测5.0才好转

iphone上老问题,不能自动播放(省流量啊,省你妹!!!),并且默认就是全屏控件播放

很长一段时间里,我都没理会这个视频处理,安卓用底层,iphone直接用VideoJS,内置flash与h5切换的,flash也有支持问题

前阵子老板有个需求,我们应用动画太多了,都是精灵路线的组合动画,一个app下来上百M
到几百M不等

所以急需有一个方案可以压缩图片

最后的方案是采用视频代替动画,因为视频压缩技术发展了很多年,已经十分成熟了。现在视频压缩技术,能够很轻松地将720P的

高清电影,压缩到10M/分钟,或者160K/秒。比图像序列的文件尺寸,至少小了几十倍。同时,在于大部分设备,都支持对视频的

硬件解压缩,这样呢,视频播放的CPU消耗很低,电池消耗也很低,同时播放速度还快。即使25帧的全屏幕播放,也能轻易地实

现。

方案定下来,需要解决的几个问题就来了

  1. 整个视频,包括视频中的某些物体,能够响应用户的点击、滑动之类的操作
  2. 在iPhone下面,可以在一个窗口中播放
  3. 能够过滤掉背景,从而能像PNG图像一样运用

最后的实际效果也是开始gif动画所示:

视频代替了动画,然后支持背景蒙板效果,能够透出底图

同时也解决了,手动,自动,不全屏的问题

iphone窗口化

解决方案:

通过canvas + video标签结合处理

原理: 获取video的原图帧,通过canavs绘制到页面

这里我直接附上源码把,代码写的一般,但是突出了几个重点

1 赞 2 收藏 1
评论

图片 2

详解移动端HTML5音频与视频问题及解决方案,html5音频

最近在研究用视频代替动画,用视频代替精灵动画,我们称这种视频叫做交互视频。

传统的精灵动画:

  1. 磁盘空间大,下载慢,尤其是在线播放,会更慢
  2. 文件太多,在线播放的时候,太多http请求,会导致响应慢,或者行为失常

因此,急需开发了一套技术,用视频代替精灵动画。我们称这种视频叫做交互视频

传统视频的问题:

  1. 传统视频,只能在方块形的区域中播放
  2. 传统的视频,在iPad下是窗口播放,在iPhone下面,只能全屏播放
  3. 传统的视频,播放的时候,一定会出现在最前端

交互视频具有如下特点:

  1. 在iPhone下面,不需要全屏播放,可以在一个区域中播放
  2. 交互视频可以出现在普通图形对象的下面
  3. 交互视频可以带有蒙板,这样可以去掉视频的背景,让视频和普通图形对象融为一体

 总结:单纯播放用的视频,我们就将其设置为传统视频。而需要用于特定用途的视频,我们就将其设置为交互视频。

其研究已经初步有成果了,顺便总结下几年移动H5开发中音频与视频遇到的实际问题及给出自己的解决方案

看下最后实际效果:兼容PC(>IE9) ,iphone,ipad, 安卓5.0

解决了iphone上,手动、自动、窗口化等问题,基本能用于实际生产了

右边是原视频mp4文件

左边视频代替了动画,然后支持背景蒙板效果,能够透出底图,支持一系列的交互操作

图片 3

H5 audio音频

每次通过 new Audio
一个音频对象,在IOS上可以看到会产生一个新的线程,这个很恶心

解决方案:new
Audio一个对象,通过替换不同的音频地址,达到不多开线程的目的

在安卓上支持不给力

解决方案:低版本安卓上的问题没解,一般是混合开发都是可以调底层接口处理的,比如
phonegap

iphone上不能自动播放

解决方案:iphone上自动播放,是IOS设计的的时候做的一个处理,貌似是为了防止自动盗用流量吧

简单来说,需要模拟用户手动去触发才可以,所以我们需要在最开始调用这样一段代码:

这是我项目上的,我就直接扣过来了

//修复ios 浏览器不能自动播放音频的问题 在加载时创建新的audio 用的时候更换src即可
Xut.fix = Xut.fix||{};
if (Xut.plat.isBrowser && Xut.plat.isIOS) {
    var isAudio = false
    var fixaudio = function() {
        if (!isAudio) {
            isAudio = true;
            Xut.fix.audio = new Audio();
            document.removeEventListener('touchstart', fixaudio, false);
        }
    };
    document.addEventListener('touchstart', fixaudio, false);
}

假如在body上绑定这样一个代码:通过手动触发创建一个audio对象,然后保存在全局中

在使用的时候如下

//如果为ios browser 用Xut.fix.audio 指定src 初始化见app.js
if (Xut.fix.audio) {
    audio 
=  Xut.fix.audio;
    audio.src = url;
} else {
    audio = new Audio(url);
}
audio.autoplay = true;
audio.play();

直接替换音频对象即可,简单来说,就是要自动就必须是用户触发创建的对象才能播

H5 video音频

视频标签可能在移动端用的很少,安卓支持太烂了,目测5.0才好转

iphone上老问题,不能自动播放(省流量啊,省你妹!!!),并且默认就是全屏控件播放

很长一段时间里,我都没理会这个视频处理,安卓用底层,iphone直接用VideoJS,内置flash与h5切换的,flash也有支持问题

前阵子老板有个需求,我们应用动画太多了,都是精灵路线的组合动画,一个app下来上百M
到几百M不等

所以急需有一个方案可以压缩图片

最后的方案是采用视频代替动画,因为视频压缩技术发展了很多年,已经十分成熟了。现在视频压缩技术,能够很轻松地将720P的高清电影,压缩到10M/分钟,或者160K/秒。比图像序列的文件尺寸,至少小了几十倍。同时,在于大部分设备,都支持对视频的硬件解压缩,这样呢,视频播放的CPU消耗很低,电池消耗也很低,同时播放速度还快。即使25帧的全屏幕播放,也能轻易地实现。

方案定下来,需要解决的几个问题就来了

1.整个视频,包括视频中的某些物体,能够响应用户的点击、滑动之类的操作
2.在iPhone下面,可以在一个窗口中播放
3.能够过滤掉背景,从而能像PNG图像一样运用

最后的实际效果也是开始gif动画所示:

视频代替了动画,然后支持背景蒙板效果,能够透出底图

同时也解决了,手动,自动,不全屏的问题 

iphone窗口化

解决方案:

通过canvas + video标签结合处理

原理: 获取video的原图帧,通过canavs绘制到页面

这里我直接附上源码把,代码写的一般,但是突出了几个重点

视频代替动画

这个有点麻烦,需要做交互,拖动canvas达到控制图像的目的,目前我还没有全部写完,一般的公司需求也不会有这个这里简单的描述下,同样是canvas
+
video处理的,但是需要有一个缓存的canvas容器做一个预处理,通过预处理,拿到每一张图的像素点,通过改变每一个像素点RBG的值,达到能够过滤掉背景,从而能像PNG图像一样运用,以后写好了,在发布吧~~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持帮客之家。

最近在研究用视频代替动画,用视频代替精灵动画,我们称这种视频叫做交互视频。…

转载自:https://blog.csdn.net/Dandelion\_drq/article/details/77645659

一、概念    

    1、物理像素 : 显示器最小的物理显示单元

    2、独立像素|CSS像素:设备宽高 375×667

    3、设备像素比:物理像素/独立像素(dpr)

<audio id="audio" autoplay='autoplay' loop='loop'>
    <source src="SeeYou.mp3" type="audio/ogg">
    <source src="SeeYou.mp3" type="audio/mpeg">
</audio>

以下是我修改的代码:
html代码:
<div class=”courseInfo”>
<p class=”picTeacher”>
<img src=”../img/Group%208%20Copy.png” />
<span class=”teacherDetial”>课程详情</span>
</p>
<p class=”audioC”>音频课程</p>
<div class=”audio-wrapper”>
<audio>

二、rem

rem = document.documentElement.clientWidth*dpr/10

图片 4

图1

 在开发webapp时,有时候你可能要加点背景音乐,这时我们会用到HTML5音频Audio。

<source
src=””
type=”audio/mp3″>
</audio>
<div class=”audio-left”><img id=”audioPlayer” src=”../img/Group
4 Copy.png”></div>
<div class=”audio-right”>
<p class=”teacherName”><span>上帝视角看民宿产业 –
马化腾</span><span
class=”tryListen”>试听三分钟</span></p>
<div class=”progress-bar-bg” id=”progressBarBg”><span
id=”progressDot”></span>
<div class=”progress-bar” id=”progressBar”></div>
</div>
<div class=”audio-time”><span class=”audio-length-current”
id=”audioCurTime”>00:00</span><span
class=”audio-length-total”></span></div>
</div>
</div>
</div>

css尺寸 = 设计稿标注尺/设计稿横向分辨率/10

 

css代码:
.audio-wrapper {
width: 90%;
margin-left: 5%;
margin: 1.2rem auto;
height: 7.357rem;
border: 1px solid #e0e0e0;
background: #FFFFFF;
box-shadow: 0 2px 0.857rem 0 rgba(0,0,0,0.07);
border-radius: 0.571rem;
}
.audio-left {
float: left;
text-align: center;
width: 16%;
height: 100%;
}
.audio-left img {
width: 2.285rem;
position: relative;
top: 2.785rem;
margin: 0;
display: initial; /* 解除与app的样式冲突 /
cursor: pointer;
}
.audio-right {
margin-right: 2%;
float: right;
width: 82%;
height: 100%;
}
.audio-right p {
height: 35%;
margin: 1.142rem 0;
/
歌曲名称只显示在一行,超出部分显示为省略号 */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-family: PingFang-SC-Medium;
font-size: 0.928rem;
color: #333333;
}
.progress-bar-bg {
position: relative;
height: 0.428rem;
width: 94%;
margin-top: -1.3rem;
margin-left: .5rem;
cursor: pointer;
background: #F6F5F8;
border-radius: 0.571rem;
}
.progress-bar {
width: 0;
height: 0.428rem;
background: #3D7ADE;
border-radius: 0.571rem;
}
.progress-bar-bg span {
content: ” “;
width: 0.714rem;
height: 0.714rem;
border-radius: 50%;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
background-color: #3e87e8;
position: absolute;
left: 0;
top: 50%;
margin-top: -0.357rem;
margin-left: -0.357rem;
cursor: pointer;
}
.audio-time {
overflow: hidden;
margin-top: 0.629rem;
margin-left: 0.3rem;
font-family: PingFangSC-Regular;
font-size: 0.857rem;
color: #999999;
}
.audio-length-total {
float: right;
font-size: 0.857rem;
}
.audio-length-current {
float: left;
font-size: 0.857rem;
}
.teacherName{
width: 100%;
position: relative;
font-family: PingFang-SC-Medium;
font-size: 0.928rem;
color: #333333;
}
.teacherName .tryListen{
position: absolute;
right: 0.2rem;
border: 0.5px solid #FF7200;
border-radius: 0.714rem;
padding: 0.1rem 0.4rem;
font-family: PingFang-SC-Regular;
font-size: 0.785rem;
color: #FF7200;
letter-spacing: 0;
text-align: center;
}
.teacherDetial{
font-family: PingFangSC-Semibold;
font-size: 1.214rem;
color: #333333;
letter-spacing: 0;
}

做完后我们放PC端测试可以完美的进行自动播放(当然,是在你浏览器支持的情况下)。然后拿手机来试试看,你会发现有些手机里可以自动播放,而有些不能。这是为什么呢?这是因为有些手机浏览器把这个自动播放的功能给禁掉了。查阅资料可以知道,在safri
on
ios里面已经明确指出等待用户的交互动作后才能播放media,也就是说如果你没有得到用户的action就播放的话就会被safri拦截。
看到这里一般很多人以为这样可以解决:

js代码:
<script>
$(document).ready(function () {
// 控制音频文件名显示宽度
var maxW = $(‘.audio-right’).width();
$(‘.audio-right p’).css({
“max-width”: maxW
});

 

        initAudioEvent();
    });

    /**
     * 初始化音频控制事件
     */
    function initAudioEvent() {
        var audio = $('audio')[0];
        console.log(audio.duration)
        // 点击播放/暂停图片时,控制音乐的播放与暂停
        $('#audioPlayer').click(function () {
            if(audio.currentTime >=180){
                return false;
            }
            // 监听音频播放时间并更新进度条
            audio.addEventListener('timeupdate', function () {
                updateProgress(audio);
                console.log(updateProgress(audio))
            }, false);

            // 监听播放完成事件
            audio.addEventListener('ended', function () {
                audioEnded();
            }, false);

            // 改变播放/暂停图片
            if (audio.paused) {
                // 开始播放当前点击的音频
                audio.play();
                $('#audioPlayer').attr('src', '../img/Group 33 Copy 6.png');
            } else {
                audio.pause();
                $('#audioPlayer').attr('src', '../img/Group 4 Copy.png');
            }
            console.log(audio.currentTime);
            //试听三分钟
            if(audio.currentTime >=180){
                audio.pause();
                $('#audioPlayer').attr('src', '../img/Group 4 Copy.png');
            }
        });

        // 点击进度条跳到指定点播放
        // PS:此处不要用click,否则下面的拖动进度点事件有可能在此处触发,此时e.offsetX的值非常小,会导致进度条弹回开始处(简直不能忍!!)
        $('#progressBarBg').on('mousedown', function (e) {
            // 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
            audio.currentTime = 10;
            if (!audio.paused || audio.currentTime != 0) {  //音频播放,且播放时间不为0. 如果音频暂停,则audio.paused为true
                var pgsWidth = $('.progress-bar-bg').width();
                var rate = e.offsetX / pgsWidth;
                audio.currentTime = audio.duration * rate;   //在火狐、IE浏览器中设置成功,但是在chrome中失败。解决方案:将src把音频/视频放到服务器,使用http://的播放地址
                console.log(audio.currentTime)
                //试听三分钟
                if(audio.currentTime >=180){
                    audio.pause();
                    $('#audioPlayer').attr('src', '../img/Group 4 Copy.png');
                }
                updateProgress(audio);
            }
        });

        var dot = document.getElementById('progressDot');

        // 鼠标拖动进度点时可以调节进度
        // 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
        // 鼠标按下时
        dot.onmousedown = function (e) {
            if (!audio.paused || audio.currentTime != 0) {
                var oriLeft = dot.offsetLeft;
                var mouseX = e.clientX;
                var maxLeft = oriLeft; // 向左最大可拖动距离
                var maxRight = document.getElementById('progressBarBg').offsetWidth - oriLeft; // 向右最大可拖动距离

                // 禁止默认的选中事件(避免鼠标拖拽进度点的时候选中文字)
                if (e.preventDefault) {
                    e.preventDefault();
                } else {
                    e.returnValue = false;
                }

                // 禁止事件冒泡
                if (e && e.stopPropagation) {
                    e.stopPropagation();
                } else {
                    window.event.cancelBubble = true;
                }

                // 开始拖动
                document.onmousemove = function (e) {
                    var length = e.clientX - mouseX;
                    if (length > maxRight) {
                        length = maxRight;
                    } else if (length < -maxLeft) {
                        length = -maxLeft;
                    }
                    var pgsWidth = $('.progress-bar-bg').width();
                    var rate = (oriLeft + length) / pgsWidth;
                    audio.currentTime = audio.duration * rate;
                    updateProgress(audio);
                };

                // 拖动结束
                document.onmouseup = function () {
                    document.onmousemove = null;
                    document.onmouseup = null;
                };
            }
        };
    }

    /**
     * 更新进度条与当前播放时间
     * @param  audio - audio对象
     */
    function updateProgress(audio) {
        var value = audio.currentTime / audio.duration;
        $('#progressBar').css('width', value * 100 + '%');
        $('#progressDot').css('left', value * 100 + '%');
        $('#audioCurTime').html(transTime(audio.currentTime));
        $('.audio-length-total').text(transTime(audio.duration));
        if(audio.currentTime >= 180){
            audio.pause();
            $('#audioPlayer').attr('src', '../img/Group 4 Copy.png');   
        }

    }       
    /**
     * 播放完成时把进度调回开始的位置
     */
    function audioEnded() {
        $('#progressBar').css('width', 0);
        $('#progressDot').css('left', 0);
        $('#audioPlayer').attr('src', '../img/Group 4 Copy.png');
    }

    /**
     * 音频播放时间换算
     * @param {number} value - 音频当前播放时间,单位秒
     */
    function transTime(value) {
        var time = "";
        var h = parseInt(value / 3600);
        value %= 3600;
        var m = parseInt(value / 60);
        var s = parseInt(value % 60);
        if (h > 0) {
            time = formatTime(h + ":" + m + ":" + s);
        } else {
            time = formatTime(m + ":" + s);
        }

        return time;
    }

    /**
     * 格式化时间显示,补零对齐
     * eg:2:4  -->  02:04
     * @param {string} value - 形如 h:m:s 的字符串 
     */
    function formatTime(value) {
        var time = "";
        var s = value.split(':');
        var i = 0;
        for (; i < s.length - 1; i++) {
            time += s[i].length == 1 ? ("0" + s[i]) : s[i];
            time += ":";
        }
        time += s[i].length == 1 ? ("0" + s[i]) : s[i];

        return time;
    }
</script>
var audio = document.getElementById('audio');
window.onload=function(){
    audio.play();
}

其实这样你还是没有和浏览器进行交互的,是不行的。
那么我们还有其它的解决方案么?其实有个障眼法的解决方法:
在我们一般打开手机网站,我们的手指是不是会不经意的就碰到了屏幕,想到这里,这样我们就可以给html或body添加个这样的事件:

 

$('html').on('touchstart',function(){
audio.play();
});

 

 这样就OK了。但我们有可能会加个按钮来控制音乐的开关。这样后面发现,我可能不想听这背景音乐,只想静静的浏览页面,当我点击关闭音乐按钮后,我继续浏览页面,这时手碰到了屏幕,声音又播放了,可是我之前关闭音乐就是为了不想它播放,显然这样是不好的,所以感觉要用one()才更合适,让它只能运行一次该事件处理函数。

$('html').one('touchstart',function(){
    audio.play();
});

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图