-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathvideoHandle.js
146 lines (131 loc) · 4.78 KB
/
videoHandle.js
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
/**
* 处理视频流到bilibili直播上
*/
const ffmpeg = require('fluent-ffmpeg');
const _ = require('lodash');
const fs = require('fs');
const logger = require('./logger');
const waterMarkList = require('./config/waterMarkList');
const helper = require('./helper');
module.exports = {
/**
* 推流
* @param {String} chapter 推流文件
* @param {Object} liveInfo 直播信息
* @return {Promise}
*/
pushStream : function(chapter,liveInfo) {
let section = helper.getChapterFileName(chapter);
let starttime = chapter.starttime ? chapter.starttime : 0;
let duration = chapter.duration;
console.log(section);
return new Promise((reslove,reject) => {
ffmpeg.ffprobe(`${__dirname}/data/${section}/${section}`, function(err, metadata) {
if(err){
reject(err);
}
let stream = null;
if(!_.isEmpty(metadata)){
stream = metadata.streams.find((value,index) => {
return value.codec_type === 'video';
});
}
if(!_.isEmpty(stream)){
if(stream.width/stream.height > 1.3 && stream.width/stream.height < 1.4) reslove('4:3');
else if(stream.width/stream.height > 1.7 && stream.width/stream.height < 1.8) reslove('16:9');
else reject(new Error('此视频暂时无法解析'));
}
else{
reject(new Error('没有找到视频'));
}
});
}).then((aspect) => {
return new Promise((reslove ,reject) => {
//判断是否需要添加字幕
let hasSubtitles = fs.existsSync(`${__dirname}/data/${section}/sc.ass`);
let inputPath = `${__dirname}/data/${section}/${section}`;
let outputPath = `${liveInfo.rtmpUrl}/${liveInfo.rtmpCode}`;
let videoW = null;
let videoH = null;
let screenW = null;
let screenH = null;
if(aspect === '4:3'){
videoW = 640;
videoH = 480;
screenW = 800;
screenH = 480;
}else if(aspect === '16:9'){
videoW = 1024;
videoH = 600;
screenW = 1024;
screenH = 600;
}
let x = (screenW - videoW)/2;
let filterList = [
{
filter: 'scale',
options: {
width : videoW,
height : videoH
},
inputs: ['0:v'],
outputs: ['c']
},
{
filter: 'pad',
options: {
width :screenW,
height : screenH,
x : x
},
inputs: ['c'],
outputs: ['output']
}
];
//添加字幕
if(hasSubtitles){
filterList.push({
filter: 'subtitles',
options: {
filename : `${__dirname}/data/${section}/sc.ass`,
},
inputs: ['output'],
outputs: ['output']
});
}
filterList = filterList.concat(waterMarkList(chapter));
var cmd = ffmpeg(inputPath);
if(duration) cmd.duration(duration);
cmd.seekInput(starttime)
.inputOptions('-re')
.inputOptions('-ac 2')
.complexFilter(filterList)
.on('start', function(commandLine) {
logger.info(`开始串流:${outputPath}`);
})
.on('error', function(err, stdout, stderr) {
logger.error('error: ' + err.message);
logger.error('stdout: ' + stdout);
logger.error('stderr: ' + stderr);
reject(err);
})
.on('end', function() {
logger.info('当前视频串流完成 !');
reslove();
})
.addOptions([
'-vcodec libx264',
'-preset veryfast',
'-crf 22',
'-maxrate 1000k',
'-bufsize 3000k',
'-acodec libmp3lame',
'-ac 2',
'-ar 44100'
])
.format('flv')
.output(outputPath,{end:false}).run();
});
});
}
};