HTML5播放.flv视频

2021,我精心制作了一张Flash新年贺卡,所有的祝福都在文字里了👇


👆 新年祝福

我的新年祝福已经送给你了,如果收不到,那只能怪Flash不争气了。

╮(╯▽╰)╭

遥想Flash当年,网页初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。那时的Flash可是神一般的存在啊,几乎所有网页都有着它的身影。可如今,就在昨天……

Flash寿终就寝了!

真的很难想象,支撑了互联网半壁江山的“跨媒体多平台工具”Flash,会在十几年后遭到 “全网封杀”。除了频频发布禁用提示的各个浏览器,甚至连其母公司Adobe也在2017年7月宣布,2021年将“抛弃”Flash,停止一切支持。

当然,被淘汰的Flash很大原因在于自身,Flash的漏洞实在太多了,黑客可以轻而易举入侵你的计算机,Adobe补都补不过来,放弃未免不是一个正确的决定。

除开安全性问题,自身功能过于冗杂也很棘手。使用Flash会占用较多的处理器资源,导致设备严重发热、续航缩短……这些问题使得Flash跟不上移动设备的潮流。毕竟,谁也不想在笔记本上在线看个视频,30分钟就搞到电脑没电吧?

与此同时,HTML5等更为开放的技术与标准逐渐完善,更进一步压缩了Flash的使用场景。现在主流的视频网站,都首选使用HTML5播放器,就连“FLASH始祖”4399也是如此。“浏览器必须使用Flash”的理由越来越少。


👆 4399网页界面

当然,HTML也存在缺陷(好家伙,扯了半天终于看标题了)。
(lll¬ω¬)

HTML5和浏览器对视频和音频文件格式都有严格的要求,仅有少数几种视频和音频格式的文件能够同时满足HTML5和浏览器的需求。

因此想要在网页中嵌入视频和音频文件,首先要选择正确的视频和音频文件格式。下面将对HTML5中视频和音频的一些常见格式以及浏览器的支持情况做具体介绍。

HTML5支持的视频格式在HTML5中嵌入的视频格式主要包括ogg、mpeg4、wehm等,具体介绍如下。

ogg:一种开源的视频封装容器,其视频文件扩展名为.ogg,里面可以封装vobris音频编码或者theora视频编码,同时ogg文件也能将音频编码和视频编码进行混合封装。

mpeg4:目前最流行的视频格式,其视频文件扩展名为.mp4。同等条件下,mpeg4格式的视频质量较好,但它的专利被MPEG-LA公司控制,任何支持播放mpeg4视频的设备,都必须有一张MPEG-LA颁发的许可证。目前MPEG-LA规定,只要是互联网上免费播放的视频,均可以无偿获得使用许可证。

Webm:由Google发布的一个开放、免费的媒体文件格式,其视频文件扩展名为.webm。由于.webm格式的视频质量和mpeg4较为接近,并且没有专利限制等问题,所以.webm已经被越来越多的人所使用。

可是Flash时代还遗留着一些问题,.flv视频无法直接通过HTML5播放,很多视频网站前期完全依赖Flash播放而选择.flv格式,所以在HTML时代,让.flv在HTML上播放是不得不解决的问题。我们耳熟能详的B站当前还是使用.flv视频,且当前可以在HTML上进行播放。


👆 Bilinili弹幕网界面

这得益于前Bilibili开发者,知乎ID(谦谦)提供的flv.js方案,当前该项目已开源。根据该开发者的回答可知:

flv.js 做了三件事

  1. HTML5 原生仅支持播放 mp4/webm 格式,flv.js 实现了在 HTML5 上播放 FLV 格式视频。
  2. 使 Bilibili 网页端平滑过度到 HTML5 播放器,历史遗留不再是障碍。
  3. 对于视频直播,在 HTML5 上支持了延迟极低 HTTP FLV 播放,解开网页端直播对 Flash 的依赖。


🔗知乎链接:https://www.zhihu.com/question/51997376


🔗项目链接:https://github.com/Bilibili/flv.js

在线演示:

Demo: 点我打开在线演示

注意:

跨域会报错,有空我再写解决跨域方案,您可先打开下方链接寻求帮助:

🔗帮助链接:http://t.ssss.fun/baidu/?q=5aaC5L2V6Kej5Yaz6Leo5Z+f6Zeu6aKY

演示代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
<!DOCTYPE html>
<html>

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>flv.js demo</title>

<style>

.mainContainer {
display: block;
width: 100%;
margin-left: auto;
margin-right: auto;
}
@media screen and (min-width: 1152px) {
.mainContainer {
display: block;
width: 1152px;
margin-left: auto;
margin-right: auto;
}
}

.video-container {
position: relative;
margin-top: 8px;
}

.video-container:before {
display: block;
content: "";
width: 100%;
padding-bottom: 56.25%;
}

.video-container > div {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}

.video-container video {
width: 100%;
height: 100%;
}

.urlInput {
display: block;
width: 100%;
margin-left: auto;
margin-right: auto;
margin-top: 8px;
margin-bottom: 8px;
}

.centeredVideo {
display: block;
width: 100%;
height: 100%;
margin-left: auto;
margin-right: auto;
margin-bottom: auto;
}

.controls {
display: block;
width: 100%;
text-align: left;
margin-left: auto;
margin-right: auto;
margin-top: 8px;
margin-bottom: 10px;
}

.logcatBox {
border-color: #CCCCCC;
font-size: 11px;
font-family: Menlo, Consolas, monospace;
display: block;
width: 100%;
text-align: left;
margin-left: auto;
margin-right: auto;
}

.url-input , .options {
font-size: 13px;
}

.url-input {
display: flex;
}

.url-input label {
flex: initial;
}

.url-input input {
flex: auto;
margin-left: 8px;
}

.url-input button {
flex: initial;
margin-left: 8px;
}

.options {
margin-top: 5px;
}

.hidden {
display: none;
}

</style>

</head>

<body>

<div class="mainContainer">
<div>
<div id="streamURL">
<div class="url-input">
<label for="sURL">Stream URL:</label>
<input id="sURL" type="text" value="https://download.ssss.fun/?url=https%3A%2F%2Ffile.ssss.fun%2F%3F%2F%25E5%25A8%25B1%25E4%25B9%2590%25E4%25B8%25AD%25E5%25BF%2583%2F%25E8%25A7%2586%25E9%25A2%2591%2F%25E5%2585%25A8%25E9%2583%25A8%2F%25E5%25A4%25BA%25E5%2586%25A0.flv" />
<button onclick="switch_mds()">Switch to MediaDataSource</button>
</div>
<div class="options">
<input type="checkbox" id="isLive" onchange="saveSettings()" />
<label for="isLive">isLive</label>
<input type="checkbox" id="withCredentials" onchange="saveSettings()" />
<label for="withCredentials">withCredentials</label>
<input type="checkbox" id="hasAudio" onchange="saveSettings()" checked />
<label for="hasAudio">hasAudio</label>
<input type="checkbox" id="hasVideo" onchange="saveSettings()" checked />
<label for="hasVideo">hasVideo</label>
</div>
</div>
<div id="mediaSourceURL" class="hidden">
<div class="url-input">
<label for="msURL">MediaDataSource JsonURL:</label>
<input id="msURL" type="text" value="http://127.0.0.1/flv/7182741.json" />
<button onclick="switch_url()">Switch to URL</button>
</div>
</div>
</div>
<div class="video-container">
<div>
<video name="videoElement" class="centeredVideo" controls autoplay>
Your browser is too old which doesn't support HTML5 video.
</video>
</div>
</div>
<div class="controls">
<button onclick="flv_load()">Load</button>
<button onclick="flv_start()">Start</button>
<button onclick="flv_pause()">Pause</button>
<button onclick="flv_destroy()">Destroy</button>
<input style="width:100px" type="text" name="seekpoint"/>
<button onclick="flv_seekto()">SeekTo</button>
</div>
<textarea name="logcatbox" class="logcatBox" rows="10" readonly></textarea>
</div>

<script src="https://cdn.ssss.fun/flv.js/flv.js"></script>

<script>
var checkBoxFields = ['isLive', 'withCredentials', 'hasAudio', 'hasVideo'];
var streamURL, mediaSourceURL;

function flv_load() {
console.log('isSupported: ' + flvjs.isSupported());
if (mediaSourceURL.className === '') {
var url = document.getElementById('msURL').value;

var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
var mediaDataSource = JSON.parse(xhr.response);
flv_load_mds(mediaDataSource);
}
xhr.send();
} else {
var i;
var mediaDataSource = {
type: 'flv'
};
for (i = 0; i < checkBoxFields.length; i++) {
var field = checkBoxFields[i];
/** @type {HTMLInputElement} */
var checkbox = document.getElementById(field);
mediaDataSource[field] = checkbox.checked;
}
mediaDataSource['url'] = document.getElementById('sURL').value;
console.log('MediaDataSource', mediaDataSource);
flv_load_mds(mediaDataSource);
}
}

function flv_load_mds(mediaDataSource) {
var element = document.getElementsByName('videoElement')[0];
if (typeof player !== "undefined") {
if (player != null) {
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}
}
player = flvjs.createPlayer(mediaDataSource, {
enableWorker: false,
lazyLoadMaxDuration: 3 * 60,
seekType: 'range',
});
player.attachMediaElement(element);
player.load();
}

function flv_start() {
player.play();
}

function flv_pause() {
player.pause();
}

function flv_destroy() {
player.pause();
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}

function flv_seekto() {
var input = document.getElementsByName('seekpoint')[0];
player.currentTime = parseFloat(input.value);
}

function switch_url() {
streamURL.className = '';
mediaSourceURL.className = 'hidden';
saveSettings();
}

function switch_mds() {
streamURL.className = 'hidden';
mediaSourceURL.className = '';
saveSettings();
}

function ls_get(key, def) {
try {
var ret = localStorage.getItem('flvjs_demo.' + key);
if (ret === null) {
ret = def;
}
return ret;
} catch (e) {}
return def;
}

function ls_set(key, value) {
try {
localStorage.setItem('flvjs_demo.' + key, value);
} catch (e) {}
}

function saveSettings() {
if (mediaSourceURL.className === '') {
ls_set('inputMode', 'MediaDataSource');
} else {
ls_set('inputMode', 'StreamURL');
}
var i;
for (i = 0; i < checkBoxFields.length; i++) {
var field = checkBoxFields[i];
/** @type {HTMLInputElement} */
var checkbox = document.getElementById(field);
ls_set(field, checkbox.checked ? '1' : '0');
}
var msURL = document.getElementById('msURL');
var sURL = document.getElementById('sURL');
ls_set('msURL', msURL.value);
ls_set('sURL', sURL.value);
console.log('save');
}

function loadSettings() {
var i;
for (i = 0; i < checkBoxFields.length; i++) {
var field = checkBoxFields[i];
/** @type {HTMLInputElement} */
var checkbox = document.getElementById(field);
var c = ls_get(field, checkbox.checked ? '1' : '0');
checkbox.checked = c === '1' ? true : false;
}

var msURL = document.getElementById('msURL');
var sURL = document.getElementById('sURL');
msURL.value = ls_get('msURL', msURL.value);
sURL.value = ls_get('sURL', sURL.value);
if (ls_get('inputMode', 'StreamURL') === 'StreamURL') {
switch_url();
} else {
switch_mds();
}
}

function showVersion() {
var version = flvjs.version;
document.title = document.title + " (v" + version + ")";
}

var logcatbox = document.getElementsByName('logcatbox')[0];
flvjs.LoggingControl.addLogListener(function(type, str) {
logcatbox.value = logcatbox.value + str + '\n';
logcatbox.scrollTop = logcatbox.scrollHeight;
});

document.addEventListener('DOMContentLoaded', function () {
streamURL = document.getElementById('streamURL');
mediaSourceURL = document.getElementById('mediaSourceURL');
loadSettings();
showVersion();
flv_load();
});
</script>

</body>

</html>