正在显示
3 个修改的文件
包含
224 行增加
和
130 行删除
| @@ -126,7 +126,7 @@ Supported operating systems and hardware: | @@ -126,7 +126,7 @@ Supported operating systems and hardware: | ||
| 126 | 16. support live stream transcoding by ffmpeg.<br/> | 126 | 16. support live stream transcoding by ffmpeg.<br/> |
| 127 | 17. support live stream transcoding by ffmpeg.<br/> | 127 | 17. support live stream transcoding by ffmpeg.<br/> |
| 128 | 18. support ffmpeg filters(logo/overlay/crop), x264 params.<br/> | 128 | 18. support ffmpeg filters(logo/overlay/crop), x264 params.<br/> |
| 129 | -19. [dev] support audio transcode only, speex/mp3 to aac<br/> | 129 | +19. support audio transcode only, speex/mp3 to aac<br/> |
| 130 | 20. [plan] support network based cli and json result.<br/> | 130 | 20. [plan] support network based cli and json result.<br/> |
| 131 | 21. [plan] support http callback api hooks(for authentication).<br/> | 131 | 21. [plan] support http callback api hooks(for authentication).<br/> |
| 132 | 22. [plan] support bandwidth test api and flash client.<br/> | 132 | 22. [plan] support bandwidth test api and flash client.<br/> |
| @@ -15,6 +15,7 @@ log_dir ./objs/logs; | @@ -15,6 +15,7 @@ log_dir ./objs/logs; | ||
| 15 | # default: 2000 | 15 | # default: 2000 |
| 16 | max_connections 2000; | 16 | max_connections 2000; |
| 17 | # vhost list, the __defaultVhost__ is the default vhost | 17 | # vhost list, the __defaultVhost__ is the default vhost |
| 18 | +# for example, user use ip to access the stream: rtmp://192.168.1.2/live/livestream. | ||
| 18 | # for which cannot identify the required vhost. | 19 | # for which cannot identify the required vhost. |
| 19 | # for default demo. | 20 | # for default demo. |
| 20 | vhost __defaultVhost__ { | 21 | vhost __defaultVhost__ { |
| @@ -44,7 +45,7 @@ vhost __defaultVhost__ { | @@ -44,7 +45,7 @@ vhost __defaultVhost__ { | ||
| 44 | vparams { | 45 | vparams { |
| 45 | } | 46 | } |
| 46 | acodec libaacplus; | 47 | acodec libaacplus; |
| 47 | - abitrate 30; | 48 | + abitrate 45; |
| 48 | asample_rate 44100; | 49 | asample_rate 44100; |
| 49 | achannels 2; | 50 | achannels 2; |
| 50 | aparams { | 51 | aparams { |
| @@ -90,7 +91,7 @@ vhost dev { | @@ -90,7 +91,7 @@ vhost dev { | ||
| 90 | enabled on; | 91 | enabled on; |
| 91 | ffmpeg ./objs/ffmpeg/bin/ffmpeg; | 92 | ffmpeg ./objs/ffmpeg/bin/ffmpeg; |
| 92 | engine dev { | 93 | engine dev { |
| 93 | - enabled on; | 94 | + enabled off; |
| 94 | vfilter { | 95 | vfilter { |
| 95 | } | 96 | } |
| 96 | vcodec libx264; | 97 | vcodec libx264; |
| @@ -104,7 +105,18 @@ vhost dev { | @@ -104,7 +105,18 @@ vhost dev { | ||
| 104 | vparams { | 105 | vparams { |
| 105 | } | 106 | } |
| 106 | acodec libaacplus; | 107 | acodec libaacplus; |
| 107 | - abitrate 30; | 108 | + abitrate 45; |
| 109 | + asample_rate 44100; | ||
| 110 | + achannels 2; | ||
| 111 | + aparams { | ||
| 112 | + } | ||
| 113 | + output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | ||
| 114 | + } | ||
| 115 | + engine dev_acodec { | ||
| 116 | + enabled on; | ||
| 117 | + vcodec copy; | ||
| 118 | + acodec libaacplus; | ||
| 119 | + abitrate 45; | ||
| 108 | asample_rate 44100; | 120 | asample_rate 44100; |
| 109 | achannels 2; | 121 | achannels 2; |
| 110 | aparams { | 122 | aparams { |
| @@ -134,7 +146,7 @@ vhost mirror.transcode.vhost.com { | @@ -134,7 +146,7 @@ vhost mirror.transcode.vhost.com { | ||
| 134 | vparams { | 146 | vparams { |
| 135 | } | 147 | } |
| 136 | acodec libaacplus; | 148 | acodec libaacplus; |
| 137 | - abitrate 30; | 149 | + abitrate 45; |
| 138 | asample_rate 44100; | 150 | asample_rate 44100; |
| 139 | achannels 2; | 151 | achannels 2; |
| 140 | aparams { | 152 | aparams { |
| @@ -164,7 +176,7 @@ vhost drawtext.transcode.vhost.com { | @@ -164,7 +176,7 @@ vhost drawtext.transcode.vhost.com { | ||
| 164 | vparams { | 176 | vparams { |
| 165 | } | 177 | } |
| 166 | acodec libaacplus; | 178 | acodec libaacplus; |
| 167 | - abitrate 30; | 179 | + abitrate 45; |
| 168 | asample_rate 44100; | 180 | asample_rate 44100; |
| 169 | achannels 2; | 181 | achannels 2; |
| 170 | aparams { | 182 | aparams { |
| @@ -194,7 +206,7 @@ vhost crop.transcode.vhost.com { | @@ -194,7 +206,7 @@ vhost crop.transcode.vhost.com { | ||
| 194 | vparams { | 206 | vparams { |
| 195 | } | 207 | } |
| 196 | acodec libaacplus; | 208 | acodec libaacplus; |
| 197 | - abitrate 30; | 209 | + abitrate 45; |
| 198 | asample_rate 44100; | 210 | asample_rate 44100; |
| 199 | achannels 2; | 211 | achannels 2; |
| 200 | aparams { | 212 | aparams { |
| @@ -224,7 +236,7 @@ vhost logo.transcode.vhost.com { | @@ -224,7 +236,7 @@ vhost logo.transcode.vhost.com { | ||
| 224 | vparams { | 236 | vparams { |
| 225 | } | 237 | } |
| 226 | acodec libaacplus; | 238 | acodec libaacplus; |
| 227 | - abitrate 30; | 239 | + abitrate 45; |
| 228 | asample_rate 44100; | 240 | asample_rate 44100; |
| 229 | achannels 2; | 241 | achannels 2; |
| 230 | aparams { | 242 | aparams { |
| @@ -233,6 +245,40 @@ vhost logo.transcode.vhost.com { | @@ -233,6 +245,40 @@ vhost logo.transcode.vhost.com { | ||
| 233 | } | 245 | } |
| 234 | } | 246 | } |
| 235 | } | 247 | } |
| 248 | +# audio transcode only. | ||
| 249 | +# for example, FMLE publish audio codec in mp3, and donot support HLS output, | ||
| 250 | +# we can transcode the audio to aac and copy video to the new stream with HLS. | ||
| 251 | +vhost audio.transcode.vhost.com { | ||
| 252 | + transcode { | ||
| 253 | + enabled on; | ||
| 254 | + ffmpeg ./objs/ffmpeg/bin/ffmpeg; | ||
| 255 | + engine acodec { | ||
| 256 | + enabled on; | ||
| 257 | + vcodec copy; | ||
| 258 | + acodec libaacplus; | ||
| 259 | + abitrate 45; | ||
| 260 | + asample_rate 44100; | ||
| 261 | + achannels 2; | ||
| 262 | + aparams { | ||
| 263 | + } | ||
| 264 | + output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | ||
| 265 | + } | ||
| 266 | + } | ||
| 267 | +} | ||
| 268 | +# ffmpeg-copy(forward implements by ffmpeg). | ||
| 269 | +# copy the video and audio to a new stream. | ||
| 270 | +vhost copy.transcode.vhost.com { | ||
| 271 | + transcode { | ||
| 272 | + enabled on; | ||
| 273 | + ffmpeg ./objs/ffmpeg/bin/ffmpeg; | ||
| 274 | + engine copy { | ||
| 275 | + enabled on; | ||
| 276 | + vcodec copy; | ||
| 277 | + acodec copy; | ||
| 278 | + output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | ||
| 279 | + } | ||
| 280 | + } | ||
| 281 | +} | ||
| 236 | # transcode all app and stream of vhost | 282 | # transcode all app and stream of vhost |
| 237 | vhost all.transcode.vhost.com { | 283 | vhost all.transcode.vhost.com { |
| 238 | # the streaming transcode configs. | 284 | # the streaming transcode configs. |
| @@ -258,7 +304,9 @@ vhost all.transcode.vhost.com { | @@ -258,7 +304,9 @@ vhost all.transcode.vhost.com { | ||
| 258 | # for filters, @see: http://ffmpeg.org/ffmpeg-filters.html | 304 | # for filters, @see: http://ffmpeg.org/ffmpeg-filters.html |
| 259 | filter_complex 'overlay=10:10'; | 305 | filter_complex 'overlay=10:10'; |
| 260 | } | 306 | } |
| 261 | - # video encoder name | 307 | + # video encoder name. can be: |
| 308 | + # libx264: use h.264(libx264) video encoder. | ||
| 309 | + # copy: donot encoder the video stream, copy it. | ||
| 262 | vcodec libx264; | 310 | vcodec libx264; |
| 263 | # video bitrate, in kbps | 311 | # video bitrate, in kbps |
| 264 | vbitrate 1500; | 312 | vbitrate 1500; |
| @@ -287,7 +335,9 @@ vhost all.transcode.vhost.com { | @@ -287,7 +335,9 @@ vhost all.transcode.vhost.com { | ||
| 287 | bf 3; | 335 | bf 3; |
| 288 | refs 10; | 336 | refs 10; |
| 289 | } | 337 | } |
| 290 | - # audio encoder name | 338 | + # audio encoder name. can be: |
| 339 | + # libaacplus: use aac(libaacplus) audio encoder. | ||
| 340 | + # copy: donot encoder the audio stream, copy it. | ||
| 291 | acodec libaacplus; | 341 | acodec libaacplus; |
| 292 | # audio bitrate, in kbps. [16, 72] for libaacplus. | 342 | # audio bitrate, in kbps. [16, 72] for libaacplus. |
| 293 | abitrate 70; | 343 | abitrate 70; |
| @@ -362,13 +412,45 @@ vhost all.transcode.vhost.com { | @@ -362,13 +412,45 @@ vhost all.transcode.vhost.com { | ||
| 362 | vparams { | 412 | vparams { |
| 363 | } | 413 | } |
| 364 | acodec libaacplus; | 414 | acodec libaacplus; |
| 365 | - abitrate 30; | 415 | + abitrate 45; |
| 416 | + asample_rate 44100; | ||
| 417 | + achannels 2; | ||
| 418 | + aparams { | ||
| 419 | + } | ||
| 420 | + output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | ||
| 421 | + } | ||
| 422 | + engine vcopy { | ||
| 423 | + enabled on; | ||
| 424 | + vcodec copy; | ||
| 425 | + acodec libaacplus; | ||
| 426 | + abitrate 45; | ||
| 366 | asample_rate 44100; | 427 | asample_rate 44100; |
| 367 | achannels 2; | 428 | achannels 2; |
| 368 | aparams { | 429 | aparams { |
| 369 | } | 430 | } |
| 370 | output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | 431 | output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; |
| 371 | } | 432 | } |
| 433 | + engine acopy { | ||
| 434 | + enabled on; | ||
| 435 | + vcodec libx264; | ||
| 436 | + vbitrate 300; | ||
| 437 | + vfps 20; | ||
| 438 | + vwidth 768; | ||
| 439 | + vheight 320; | ||
| 440 | + vthreads 2; | ||
| 441 | + vprofile baseline; | ||
| 442 | + vpreset superfast; | ||
| 443 | + vparams { | ||
| 444 | + } | ||
| 445 | + acodec copy; | ||
| 446 | + output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | ||
| 447 | + } | ||
| 448 | + engine copy { | ||
| 449 | + enabled on; | ||
| 450 | + vcodec copy; | ||
| 451 | + acodec copy; | ||
| 452 | + output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | ||
| 453 | + } | ||
| 372 | } | 454 | } |
| 373 | } | 455 | } |
| 374 | # transcode all stream using the empty ffmpeg demo, donothing. | 456 | # transcode all stream using the empty ffmpeg demo, donothing. |
| @@ -389,7 +471,7 @@ vhost ffempty.transcode.vhost.com { | @@ -389,7 +471,7 @@ vhost ffempty.transcode.vhost.com { | ||
| 389 | vparams { | 471 | vparams { |
| 390 | } | 472 | } |
| 391 | acodec libaacplus; | 473 | acodec libaacplus; |
| 392 | - abitrate 30; | 474 | + abitrate 45; |
| 393 | asample_rate 44100; | 475 | asample_rate 44100; |
| 394 | achannels 2; | 476 | achannels 2; |
| 395 | aparams { | 477 | aparams { |
| @@ -42,8 +42,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -42,8 +42,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 42 | 42 | ||
| 43 | #define SRS_ENCODER_SLEEP_MS 2000 | 43 | #define SRS_ENCODER_SLEEP_MS 2000 |
| 44 | 44 | ||
| 45 | -#define SRS_ENCODER_VCODEC "libx264" | ||
| 46 | -#define SRS_ENCODER_ACODEC "libaacplus" | 45 | +#define SRS_ENCODER_COPY "copy" |
| 46 | +#define SRS_ENCODER_VCODEC "libx264" | ||
| 47 | +#define SRS_ENCODER_ACODEC "libaacplus" | ||
| 47 | 48 | ||
| 48 | // for encoder to detect the dead loop | 49 | // for encoder to detect the dead loop |
| 49 | static std::vector<std::string> _transcoded_url; | 50 | static std::vector<std::string> _transcoded_url; |
| @@ -138,70 +139,75 @@ int SrsFFMPEG::initialize(SrsRequest* req, SrsConfDirective* engine) | @@ -138,70 +139,75 @@ int SrsFFMPEG::initialize(SrsRequest* req, SrsConfDirective* engine) | ||
| 138 | } | 139 | } |
| 139 | _transcoded_url.push_back(output); | 140 | _transcoded_url.push_back(output); |
| 140 | 141 | ||
| 141 | - if (vcodec != SRS_ENCODER_VCODEC) { | ||
| 142 | - ret = ERROR_ENCODER_VCODEC; | ||
| 143 | - srs_error("invalid vcodec, must be %s, actual %s, ret=%d", | ||
| 144 | - SRS_ENCODER_VCODEC, vcodec.c_str(), ret); | ||
| 145 | - return ret; | ||
| 146 | - } | ||
| 147 | - if (vbitrate <= 0) { | ||
| 148 | - ret = ERROR_ENCODER_VBITRATE; | ||
| 149 | - srs_error("invalid vbitrate: %d, ret=%d", vbitrate, ret); | ||
| 150 | - return ret; | ||
| 151 | - } | ||
| 152 | - if (vfps <= 0) { | ||
| 153 | - ret = ERROR_ENCODER_VFPS; | ||
| 154 | - srs_error("invalid vfps: %.2f, ret=%d", vfps, ret); | ||
| 155 | - return ret; | ||
| 156 | - } | ||
| 157 | - if (vwidth <= 0) { | ||
| 158 | - ret = ERROR_ENCODER_VWIDTH; | ||
| 159 | - srs_error("invalid vwidth: %d, ret=%d", vwidth, ret); | ||
| 160 | - return ret; | ||
| 161 | - } | ||
| 162 | - if (vheight <= 0) { | ||
| 163 | - ret = ERROR_ENCODER_VHEIGHT; | ||
| 164 | - srs_error("invalid vheight: %d, ret=%d", vheight, ret); | ||
| 165 | - return ret; | ||
| 166 | - } | ||
| 167 | - if (vthreads < 0) { | ||
| 168 | - ret = ERROR_ENCODER_VTHREADS; | ||
| 169 | - srs_error("invalid vthreads: %d, ret=%d", vthreads, ret); | ||
| 170 | - return ret; | ||
| 171 | - } | ||
| 172 | - if (vprofile.empty()) { | ||
| 173 | - ret = ERROR_ENCODER_VPROFILE; | ||
| 174 | - srs_error("invalid vprofile: %s, ret=%d", vprofile.c_str(), ret); | ||
| 175 | - return ret; | ||
| 176 | - } | ||
| 177 | - if (vpreset.empty()) { | ||
| 178 | - ret = ERROR_ENCODER_VPRESET; | ||
| 179 | - srs_error("invalid vpreset: %s, ret=%d", vpreset.c_str(), ret); | ||
| 180 | - return ret; | ||
| 181 | - } | ||
| 182 | - if (acodec != SRS_ENCODER_ACODEC) { | ||
| 183 | - ret = ERROR_ENCODER_ACODEC; | ||
| 184 | - srs_error("invalid acodec, must be %s, actual %s, ret=%d", | ||
| 185 | - SRS_ENCODER_ACODEC, acodec.c_str(), ret); | ||
| 186 | - return ret; | ||
| 187 | - } | ||
| 188 | - if (abitrate <= 0) { | ||
| 189 | - ret = ERROR_ENCODER_ABITRATE; | ||
| 190 | - srs_error("invalid abitrate: %d, ret=%d", | ||
| 191 | - abitrate, ret); | ||
| 192 | - return ret; | ||
| 193 | - } | ||
| 194 | - if (asample_rate <= 0) { | ||
| 195 | - ret = ERROR_ENCODER_ASAMPLE_RATE; | ||
| 196 | - srs_error("invalid sample rate: %d, ret=%d", | ||
| 197 | - asample_rate, ret); | ||
| 198 | - return ret; | 142 | + if (vcodec != SRS_ENCODER_COPY) { |
| 143 | + if (vcodec != SRS_ENCODER_VCODEC) { | ||
| 144 | + ret = ERROR_ENCODER_VCODEC; | ||
| 145 | + srs_error("invalid vcodec, must be %s, actual %s, ret=%d", | ||
| 146 | + SRS_ENCODER_VCODEC, vcodec.c_str(), ret); | ||
| 147 | + return ret; | ||
| 148 | + } | ||
| 149 | + if (vbitrate <= 0) { | ||
| 150 | + ret = ERROR_ENCODER_VBITRATE; | ||
| 151 | + srs_error("invalid vbitrate: %d, ret=%d", vbitrate, ret); | ||
| 152 | + return ret; | ||
| 153 | + } | ||
| 154 | + if (vfps <= 0) { | ||
| 155 | + ret = ERROR_ENCODER_VFPS; | ||
| 156 | + srs_error("invalid vfps: %.2f, ret=%d", vfps, ret); | ||
| 157 | + return ret; | ||
| 158 | + } | ||
| 159 | + if (vwidth <= 0) { | ||
| 160 | + ret = ERROR_ENCODER_VWIDTH; | ||
| 161 | + srs_error("invalid vwidth: %d, ret=%d", vwidth, ret); | ||
| 162 | + return ret; | ||
| 163 | + } | ||
| 164 | + if (vheight <= 0) { | ||
| 165 | + ret = ERROR_ENCODER_VHEIGHT; | ||
| 166 | + srs_error("invalid vheight: %d, ret=%d", vheight, ret); | ||
| 167 | + return ret; | ||
| 168 | + } | ||
| 169 | + if (vthreads < 0) { | ||
| 170 | + ret = ERROR_ENCODER_VTHREADS; | ||
| 171 | + srs_error("invalid vthreads: %d, ret=%d", vthreads, ret); | ||
| 172 | + return ret; | ||
| 173 | + } | ||
| 174 | + if (vprofile.empty()) { | ||
| 175 | + ret = ERROR_ENCODER_VPROFILE; | ||
| 176 | + srs_error("invalid vprofile: %s, ret=%d", vprofile.c_str(), ret); | ||
| 177 | + return ret; | ||
| 178 | + } | ||
| 179 | + if (vpreset.empty()) { | ||
| 180 | + ret = ERROR_ENCODER_VPRESET; | ||
| 181 | + srs_error("invalid vpreset: %s, ret=%d", vpreset.c_str(), ret); | ||
| 182 | + return ret; | ||
| 183 | + } | ||
| 199 | } | 184 | } |
| 200 | - if (achannels != 1 && achannels != 2) { | ||
| 201 | - ret = ERROR_ENCODER_ACHANNELS; | ||
| 202 | - srs_error("invalid achannels, must be 1 or 2, actual %d, ret=%d", | ||
| 203 | - achannels, ret); | ||
| 204 | - return ret; | 185 | + |
| 186 | + if (acodec != SRS_ENCODER_COPY) { | ||
| 187 | + if (acodec != SRS_ENCODER_ACODEC) { | ||
| 188 | + ret = ERROR_ENCODER_ACODEC; | ||
| 189 | + srs_error("invalid acodec, must be %s, actual %s, ret=%d", | ||
| 190 | + SRS_ENCODER_ACODEC, acodec.c_str(), ret); | ||
| 191 | + return ret; | ||
| 192 | + } | ||
| 193 | + if (abitrate <= 0) { | ||
| 194 | + ret = ERROR_ENCODER_ABITRATE; | ||
| 195 | + srs_error("invalid abitrate: %d, ret=%d", | ||
| 196 | + abitrate, ret); | ||
| 197 | + return ret; | ||
| 198 | + } | ||
| 199 | + if (asample_rate <= 0) { | ||
| 200 | + ret = ERROR_ENCODER_ASAMPLE_RATE; | ||
| 201 | + srs_error("invalid sample rate: %d, ret=%d", | ||
| 202 | + asample_rate, ret); | ||
| 203 | + return ret; | ||
| 204 | + } | ||
| 205 | + if (achannels != 1 && achannels != 2) { | ||
| 206 | + ret = ERROR_ENCODER_ACHANNELS; | ||
| 207 | + srs_error("invalid achannels, must be 1 or 2, actual %d, ret=%d", | ||
| 208 | + achannels, ret); | ||
| 209 | + return ret; | ||
| 210 | + } | ||
| 205 | } | 211 | } |
| 206 | if (output.empty()) { | 212 | if (output.empty()) { |
| 207 | ret = ERROR_ENCODER_OUTPUT; | 213 | ret = ERROR_ENCODER_OUTPUT; |
| @@ -252,40 +258,43 @@ int SrsFFMPEG::start() | @@ -252,40 +258,43 @@ int SrsFFMPEG::start() | ||
| 252 | params.push_back("-vcodec"); | 258 | params.push_back("-vcodec"); |
| 253 | params.push_back(vcodec); | 259 | params.push_back(vcodec); |
| 254 | 260 | ||
| 255 | - params.push_back("-b:v"); | ||
| 256 | - snprintf(tmp, sizeof(tmp), "%d", vbitrate * 1000); | ||
| 257 | - params.push_back(tmp); | ||
| 258 | - | ||
| 259 | - params.push_back("-r"); | ||
| 260 | - snprintf(tmp, sizeof(tmp), "%.2f", vfps); | ||
| 261 | - params.push_back(tmp); | ||
| 262 | - | ||
| 263 | - params.push_back("-s"); | ||
| 264 | - snprintf(tmp, sizeof(tmp), "%dx%d", vwidth, vheight); | ||
| 265 | - params.push_back(tmp); | ||
| 266 | - | ||
| 267 | - // TODO: add aspect if needed. | ||
| 268 | - params.push_back("-aspect"); | ||
| 269 | - snprintf(tmp, sizeof(tmp), "%d:%d", vwidth, vheight); | ||
| 270 | - params.push_back(tmp); | ||
| 271 | - | ||
| 272 | - params.push_back("-threads"); | ||
| 273 | - snprintf(tmp, sizeof(tmp), "%d", vthreads); | ||
| 274 | - params.push_back(tmp); | ||
| 275 | - | ||
| 276 | - params.push_back("-profile:v"); | ||
| 277 | - params.push_back(vprofile); | ||
| 278 | - | ||
| 279 | - params.push_back("-preset"); | ||
| 280 | - params.push_back(vpreset); | ||
| 281 | - | ||
| 282 | - // vparams | ||
| 283 | - if (!vparams.empty()) { | ||
| 284 | - std::vector<std::string>::iterator it; | ||
| 285 | - for (it = vparams.begin(); it != vparams.end(); ++it) { | ||
| 286 | - std::string p = *it; | ||
| 287 | - if (!p.empty()) { | ||
| 288 | - params.push_back(p); | 261 | + // the codec params is disabled when copy |
| 262 | + if (vcodec != SRS_ENCODER_COPY) { | ||
| 263 | + params.push_back("-b:v"); | ||
| 264 | + snprintf(tmp, sizeof(tmp), "%d", vbitrate * 1000); | ||
| 265 | + params.push_back(tmp); | ||
| 266 | + | ||
| 267 | + params.push_back("-r"); | ||
| 268 | + snprintf(tmp, sizeof(tmp), "%.2f", vfps); | ||
| 269 | + params.push_back(tmp); | ||
| 270 | + | ||
| 271 | + params.push_back("-s"); | ||
| 272 | + snprintf(tmp, sizeof(tmp), "%dx%d", vwidth, vheight); | ||
| 273 | + params.push_back(tmp); | ||
| 274 | + | ||
| 275 | + // TODO: add aspect if needed. | ||
| 276 | + params.push_back("-aspect"); | ||
| 277 | + snprintf(tmp, sizeof(tmp), "%d:%d", vwidth, vheight); | ||
| 278 | + params.push_back(tmp); | ||
| 279 | + | ||
| 280 | + params.push_back("-threads"); | ||
| 281 | + snprintf(tmp, sizeof(tmp), "%d", vthreads); | ||
| 282 | + params.push_back(tmp); | ||
| 283 | + | ||
| 284 | + params.push_back("-profile:v"); | ||
| 285 | + params.push_back(vprofile); | ||
| 286 | + | ||
| 287 | + params.push_back("-preset"); | ||
| 288 | + params.push_back(vpreset); | ||
| 289 | + | ||
| 290 | + // vparams | ||
| 291 | + if (!vparams.empty()) { | ||
| 292 | + std::vector<std::string>::iterator it; | ||
| 293 | + for (it = vparams.begin(); it != vparams.end(); ++it) { | ||
| 294 | + std::string p = *it; | ||
| 295 | + if (!p.empty()) { | ||
| 296 | + params.push_back(p); | ||
| 297 | + } | ||
| 289 | } | 298 | } |
| 290 | } | 299 | } |
| 291 | } | 300 | } |
| @@ -294,25 +303,28 @@ int SrsFFMPEG::start() | @@ -294,25 +303,28 @@ int SrsFFMPEG::start() | ||
| 294 | params.push_back("-acodec"); | 303 | params.push_back("-acodec"); |
| 295 | params.push_back(acodec); | 304 | params.push_back(acodec); |
| 296 | 305 | ||
| 297 | - params.push_back("-b:a"); | ||
| 298 | - snprintf(tmp, sizeof(tmp), "%d", abitrate * 1000); | ||
| 299 | - params.push_back(tmp); | ||
| 300 | - | ||
| 301 | - params.push_back("-ar"); | ||
| 302 | - snprintf(tmp, sizeof(tmp), "%d", asample_rate); | ||
| 303 | - params.push_back(tmp); | ||
| 304 | - | ||
| 305 | - params.push_back("-ac"); | ||
| 306 | - snprintf(tmp, sizeof(tmp), "%d", achannels); | ||
| 307 | - params.push_back(tmp); | ||
| 308 | - | ||
| 309 | - // aparams | ||
| 310 | - if (!aparams.empty()) { | ||
| 311 | - std::vector<std::string>::iterator it; | ||
| 312 | - for (it = aparams.begin(); it != aparams.end(); ++it) { | ||
| 313 | - std::string p = *it; | ||
| 314 | - if (!p.empty()) { | ||
| 315 | - params.push_back(p); | 306 | + // the codec params is disabled when copy |
| 307 | + if (acodec != SRS_ENCODER_COPY) { | ||
| 308 | + params.push_back("-b:a"); | ||
| 309 | + snprintf(tmp, sizeof(tmp), "%d", abitrate * 1000); | ||
| 310 | + params.push_back(tmp); | ||
| 311 | + | ||
| 312 | + params.push_back("-ar"); | ||
| 313 | + snprintf(tmp, sizeof(tmp), "%d", asample_rate); | ||
| 314 | + params.push_back(tmp); | ||
| 315 | + | ||
| 316 | + params.push_back("-ac"); | ||
| 317 | + snprintf(tmp, sizeof(tmp), "%d", achannels); | ||
| 318 | + params.push_back(tmp); | ||
| 319 | + | ||
| 320 | + // aparams | ||
| 321 | + if (!aparams.empty()) { | ||
| 322 | + std::vector<std::string>::iterator it; | ||
| 323 | + for (it = aparams.begin(); it != aparams.end(); ++it) { | ||
| 324 | + std::string p = *it; | ||
| 325 | + if (!p.empty()) { | ||
| 326 | + params.push_back(p); | ||
| 327 | + } | ||
| 316 | } | 328 | } |
| 317 | } | 329 | } |
| 318 | } | 330 | } |
-
请 注册 或 登录 后发表评论