├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md └── src ├── convert.rs ├── main.rs ├── sound.rs └── vpx.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "aho-corasick" 3 | version = "0.6.6" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | dependencies = [ 6 | "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 7 | ] 8 | 9 | [[package]] 10 | name = "alsa-sys" 11 | version = "0.1.2" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | dependencies = [ 14 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 15 | "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", 16 | ] 17 | 18 | [[package]] 19 | name = "ansi_term" 20 | version = "0.11.0" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | dependencies = [ 23 | "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 24 | ] 25 | 26 | [[package]] 27 | name = "arrayvec" 28 | version = "0.4.7" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | dependencies = [ 31 | "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 32 | ] 33 | 34 | [[package]] 35 | name = "atty" 36 | version = "0.2.10" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | dependencies = [ 39 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 40 | "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 41 | "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 42 | ] 43 | 44 | [[package]] 45 | name = "bindgen" 46 | version = "0.32.3" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | dependencies = [ 49 | "cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 50 | "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 51 | "clang-sys 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", 52 | "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", 53 | "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 54 | "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 55 | "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 56 | "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 57 | "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 58 | "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 59 | "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 60 | "which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 61 | ] 62 | 63 | [[package]] 64 | name = "bitflags" 65 | version = "1.0.3" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | 68 | [[package]] 69 | name = "block" 70 | version = "0.1.6" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | 73 | [[package]] 74 | name = "cc" 75 | version = "1.0.18" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | 78 | [[package]] 79 | name = "cexpr" 80 | version = "0.2.3" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | dependencies = [ 83 | "nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 84 | ] 85 | 86 | [[package]] 87 | name = "cfg-if" 88 | version = "0.1.4" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | 91 | [[package]] 92 | name = "clang-sys" 93 | version = "0.21.2" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | dependencies = [ 96 | "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 97 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 98 | "libloading 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 99 | ] 100 | 101 | [[package]] 102 | name = "clap" 103 | version = "2.32.0" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | dependencies = [ 106 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 107 | "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 108 | "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 109 | "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 110 | "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 111 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 112 | "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 113 | ] 114 | 115 | [[package]] 116 | name = "cloudabi" 117 | version = "0.0.3" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | dependencies = [ 120 | "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 121 | ] 122 | 123 | [[package]] 124 | name = "core-foundation-sys" 125 | version = "0.5.1" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | dependencies = [ 128 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 129 | ] 130 | 131 | [[package]] 132 | name = "coreaudio-rs" 133 | version = "0.9.1" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | dependencies = [ 136 | "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 137 | "coreaudio-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 138 | ] 139 | 140 | [[package]] 141 | name = "coreaudio-sys" 142 | version = "0.2.2" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | dependencies = [ 145 | "bindgen 0.32.3 (registry+https://github.com/rust-lang/crates.io-index)", 146 | ] 147 | 148 | [[package]] 149 | name = "cpal" 150 | version = "0.8.2" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | dependencies = [ 153 | "alsa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 154 | "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 155 | "coreaudio-rs 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 156 | "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 157 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 158 | "stdweb 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 159 | "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 160 | ] 161 | 162 | [[package]] 163 | name = "crossbeam-channel" 164 | version = "0.2.2" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | dependencies = [ 167 | "crossbeam-epoch 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 168 | "crossbeam-utils 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 169 | "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", 170 | "rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", 171 | "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 172 | ] 173 | 174 | [[package]] 175 | name = "crossbeam-epoch" 176 | version = "0.5.0" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | dependencies = [ 179 | "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 180 | "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 181 | "crossbeam-utils 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 182 | "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 183 | "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 184 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 185 | ] 186 | 187 | [[package]] 188 | name = "crossbeam-utils" 189 | version = "0.4.1" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | 192 | [[package]] 193 | name = "docopt" 194 | version = "1.0.0" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | dependencies = [ 197 | "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 198 | "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 199 | "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", 200 | "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", 201 | "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 202 | ] 203 | 204 | [[package]] 205 | name = "env_logger" 206 | version = "0.4.3" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | dependencies = [ 209 | "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 210 | "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 211 | ] 212 | 213 | [[package]] 214 | name = "fuchsia-zircon" 215 | version = "0.3.3" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | dependencies = [ 218 | "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 219 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 220 | ] 221 | 222 | [[package]] 223 | name = "fuchsia-zircon-sys" 224 | version = "0.3.3" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | 227 | [[package]] 228 | name = "glob" 229 | version = "0.2.11" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | 232 | [[package]] 233 | name = "kernel32-sys" 234 | version = "0.2.2" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | dependencies = [ 237 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 238 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 239 | ] 240 | 241 | [[package]] 242 | name = "lazy_static" 243 | version = "1.0.1" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | 246 | [[package]] 247 | name = "libc" 248 | version = "0.2.42" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | 251 | [[package]] 252 | name = "libloading" 253 | version = "0.4.3" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | dependencies = [ 256 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 257 | "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 258 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 259 | ] 260 | 261 | [[package]] 262 | name = "libvpx-native-sys" 263 | version = "4.0.7" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | dependencies = [ 266 | "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", 267 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 268 | ] 269 | 270 | [[package]] 271 | name = "log" 272 | version = "0.3.9" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | dependencies = [ 275 | "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 276 | ] 277 | 278 | [[package]] 279 | name = "log" 280 | version = "0.4.3" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | dependencies = [ 283 | "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 284 | ] 285 | 286 | [[package]] 287 | name = "memchr" 288 | version = "1.0.2" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | dependencies = [ 291 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 292 | ] 293 | 294 | [[package]] 295 | name = "memchr" 296 | version = "2.0.1" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | dependencies = [ 299 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 300 | ] 301 | 302 | [[package]] 303 | name = "memoffset" 304 | version = "0.2.1" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | 307 | [[package]] 308 | name = "nodrop" 309 | version = "0.1.12" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | 312 | [[package]] 313 | name = "nom" 314 | version = "3.2.1" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | dependencies = [ 317 | "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 318 | ] 319 | 320 | [[package]] 321 | name = "opus" 322 | version = "0.2.0" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | dependencies = [ 325 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 326 | "opus-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 327 | ] 328 | 329 | [[package]] 330 | name = "opus-sys" 331 | version = "0.2.1" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | dependencies = [ 334 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 335 | "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", 336 | ] 337 | 338 | [[package]] 339 | name = "owning_ref" 340 | version = "0.3.3" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | dependencies = [ 343 | "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 344 | ] 345 | 346 | [[package]] 347 | name = "parking_lot" 348 | version = "0.5.5" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | dependencies = [ 351 | "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 352 | "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", 353 | ] 354 | 355 | [[package]] 356 | name = "parking_lot_core" 357 | version = "0.2.14" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | dependencies = [ 360 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 361 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 362 | "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 363 | "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 364 | ] 365 | 366 | [[package]] 367 | name = "peeking_take_while" 368 | version = "0.1.2" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | 371 | [[package]] 372 | name = "pkg-config" 373 | version = "0.3.11" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | 376 | [[package]] 377 | name = "proc-macro2" 378 | version = "0.2.3" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | dependencies = [ 381 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 382 | ] 383 | 384 | [[package]] 385 | name = "proc-macro2" 386 | version = "0.4.6" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | dependencies = [ 389 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 390 | ] 391 | 392 | [[package]] 393 | name = "quest" 394 | version = "0.2.0" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | dependencies = [ 397 | "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 398 | "rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 399 | "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 400 | "termios 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 401 | "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 402 | ] 403 | 404 | [[package]] 405 | name = "quote" 406 | version = "0.4.2" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | dependencies = [ 409 | "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 410 | ] 411 | 412 | [[package]] 413 | name = "quote" 414 | version = "0.6.3" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | dependencies = [ 417 | "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 418 | ] 419 | 420 | [[package]] 421 | name = "rand" 422 | version = "0.4.2" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | dependencies = [ 425 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 426 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 427 | "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 428 | ] 429 | 430 | [[package]] 431 | name = "rand" 432 | version = "0.5.4" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | dependencies = [ 435 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 436 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 437 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 438 | "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 439 | "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 440 | ] 441 | 442 | [[package]] 443 | name = "rand_core" 444 | version = "0.2.1" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | 447 | [[package]] 448 | name = "redox_syscall" 449 | version = "0.1.40" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | 452 | [[package]] 453 | name = "redox_termios" 454 | version = "0.1.1" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | dependencies = [ 457 | "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 458 | ] 459 | 460 | [[package]] 461 | name = "regex" 462 | version = "0.2.11" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | dependencies = [ 465 | "aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 466 | "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 467 | "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", 468 | "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 469 | "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 470 | ] 471 | 472 | [[package]] 473 | name = "regex" 474 | version = "1.0.1" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | dependencies = [ 477 | "aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 478 | "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 479 | "regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 480 | "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 481 | "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 482 | ] 483 | 484 | [[package]] 485 | name = "regex-syntax" 486 | version = "0.5.6" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | dependencies = [ 489 | "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 490 | ] 491 | 492 | [[package]] 493 | name = "regex-syntax" 494 | version = "0.6.1" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | dependencies = [ 497 | "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 498 | ] 499 | 500 | [[package]] 501 | name = "remove_dir_all" 502 | version = "0.5.1" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | dependencies = [ 505 | "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 506 | ] 507 | 508 | [[package]] 509 | name = "rpassword" 510 | version = "2.0.0" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | dependencies = [ 513 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 514 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 515 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 516 | ] 517 | 518 | [[package]] 519 | name = "sample" 520 | version = "0.10.0" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | 523 | [[package]] 524 | name = "scopeguard" 525 | version = "0.3.3" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | 528 | [[package]] 529 | name = "scrap" 530 | version = "0.5.0" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | dependencies = [ 533 | "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 534 | "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 535 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 536 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 537 | ] 538 | 539 | [[package]] 540 | name = "semver-parser" 541 | version = "0.7.0" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | 544 | [[package]] 545 | name = "serde" 546 | version = "1.0.70" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | 549 | [[package]] 550 | name = "serde_derive" 551 | version = "1.0.70" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | dependencies = [ 554 | "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 555 | "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 556 | "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", 557 | ] 558 | 559 | [[package]] 560 | name = "smallvec" 561 | version = "0.6.2" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | 564 | [[package]] 565 | name = "srs" 566 | version = "0.2.0" 567 | dependencies = [ 568 | "cpal 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 569 | "crossbeam-channel 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 570 | "docopt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 571 | "libvpx-native-sys 4.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 572 | "opus 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 573 | "quest 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 574 | "sample 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 575 | "scrap 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 576 | "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", 577 | "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", 578 | "webm 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 579 | ] 580 | 581 | [[package]] 582 | name = "stable_deref_trait" 583 | version = "1.1.0" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | 586 | [[package]] 587 | name = "stdweb" 588 | version = "0.1.3" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | 591 | [[package]] 592 | name = "strsim" 593 | version = "0.7.0" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | 596 | [[package]] 597 | name = "syn" 598 | version = "0.14.4" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | dependencies = [ 601 | "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 602 | "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 603 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 604 | ] 605 | 606 | [[package]] 607 | name = "tempfile" 608 | version = "3.0.2" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | dependencies = [ 611 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 612 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 613 | "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 614 | "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 615 | "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 616 | ] 617 | 618 | [[package]] 619 | name = "termion" 620 | version = "1.5.1" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | dependencies = [ 623 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 624 | "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 625 | "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 626 | ] 627 | 628 | [[package]] 629 | name = "termios" 630 | version = "0.3.0" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | dependencies = [ 633 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 634 | ] 635 | 636 | [[package]] 637 | name = "textwrap" 638 | version = "0.10.0" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | dependencies = [ 641 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 642 | ] 643 | 644 | [[package]] 645 | name = "thread_local" 646 | version = "0.3.5" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | dependencies = [ 649 | "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 650 | "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 651 | ] 652 | 653 | [[package]] 654 | name = "ucd-util" 655 | version = "0.1.1" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | 658 | [[package]] 659 | name = "unicode-width" 660 | version = "0.1.5" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | 663 | [[package]] 664 | name = "unicode-xid" 665 | version = "0.1.0" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | 668 | [[package]] 669 | name = "unreachable" 670 | version = "1.0.0" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | dependencies = [ 673 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 674 | ] 675 | 676 | [[package]] 677 | name = "utf8-ranges" 678 | version = "1.0.0" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | 681 | [[package]] 682 | name = "vec_map" 683 | version = "0.8.1" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | 686 | [[package]] 687 | name = "void" 688 | version = "1.0.2" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | 691 | [[package]] 692 | name = "webm" 693 | version = "1.0.0" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | dependencies = [ 696 | "webm-sys 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 697 | ] 698 | 699 | [[package]] 700 | name = "webm-sys" 701 | version = "1.0.0" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | dependencies = [ 704 | "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", 705 | ] 706 | 707 | [[package]] 708 | name = "which" 709 | version = "1.0.5" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | dependencies = [ 712 | "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", 713 | ] 714 | 715 | [[package]] 716 | name = "winapi" 717 | version = "0.2.8" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | 720 | [[package]] 721 | name = "winapi" 722 | version = "0.3.5" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | dependencies = [ 725 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 726 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 727 | ] 728 | 729 | [[package]] 730 | name = "winapi-build" 731 | version = "0.1.1" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | 734 | [[package]] 735 | name = "winapi-i686-pc-windows-gnu" 736 | version = "0.4.0" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | 739 | [[package]] 740 | name = "winapi-x86_64-pc-windows-gnu" 741 | version = "0.4.0" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | 744 | [metadata] 745 | "checksum aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c6d463cbe7ed28720b5b489e7c083eeb8f90d08be2a0d6bb9e1ffea9ce1afa" 746 | "checksum alsa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b0edcbbf9ef68f15ae1b620f722180b82a98b6f0628d30baa6b8d2a5abc87d58" 747 | "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 748 | "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" 749 | "checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" 750 | "checksum bindgen 0.32.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b242e11a8f446f5fc7b76b37e81d737cabca562a927bd33766dac55b5f1177f" 751 | "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" 752 | "checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 753 | "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" 754 | "checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c" 755 | "checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" 756 | "checksum clang-sys 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e414af9726e1d11660801e73ccc7fb81803fb5f49e5903a25b348b2b3b480d2e" 757 | "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" 758 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 759 | "checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" 760 | "checksum coreaudio-rs 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f229761965dad3e9b11081668a6ea00f1def7aa46062321b5ec245b834f6e491" 761 | "checksum coreaudio-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "78fdbabf58d5b1f461e31b94a571c109284f384cec619a3d96e66ec55b4de82b" 762 | "checksum cpal 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d58ae1ed6536b1b233f5e3aeb6997a046ddb4d05e3f61701b58a92eb254a829e" 763 | "checksum crossbeam-channel 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "258f3c07af0255827670241eacc8b0af7dbfc363df537ad062c6c515ca4a32ee" 764 | "checksum crossbeam-epoch 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48deb8586d997ab13e98fb7e057b232149f9440321c73845b2f4cee483da29bc" 765 | "checksum crossbeam-utils 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ea52fab26a99d96cdff39d0ca75c9716125937f5dba2ab83923aaaf5928f684a" 766 | "checksum docopt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e67fb750c36fc6fffbd3575cf8f2b46790fc0b05096ae3c03a36cf71b55e1e2b" 767 | "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" 768 | "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 769 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 770 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 771 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 772 | "checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" 773 | "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" 774 | "checksum libloading 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd38073de8f7965d0c17d30546d4bb6da311ab428d1c7a3fc71dff7f9d4979b9" 775 | "checksum libvpx-native-sys 4.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c57fe9856a6375cf014c480ba6467365bafd51bf0554d3a5bd7311e0c9f7ab5c" 776 | "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" 777 | "checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2" 778 | "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" 779 | "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" 780 | "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" 781 | "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" 782 | "checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b" 783 | "checksum opus 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c1ea29ab439d0852a1d991c9fa8fa8e3f31aa82f938c42ed442831d08ead0db" 784 | "checksum opus-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fad8b294f482f7972fa466b1c64d5a564e4ee6975599d80483ee4fa83f25b6ec" 785 | "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" 786 | "checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac" 787 | "checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" 788 | "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 789 | "checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" 790 | "checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" 791 | "checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6" 792 | "checksum quest 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5135783db09f76d0330e64cc5a59610eb99efacdc13be08333c2304886fc755" 793 | "checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" 794 | "checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035" 795 | "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" 796 | "checksum rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "12397506224b2f93e6664ffc4f664b29be8208e5157d3d90b44f09b5fae470ea" 797 | "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" 798 | "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" 799 | "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" 800 | "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" 801 | "checksum regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13c93d55961981ba9226a213b385216f83ab43bd6ac53ab16b2eeb47e337cf4e" 802 | "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" 803 | "checksum regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05b06a75f5217880fc5e905952a42750bf44787e56a6c6d6852ed0992f5e1d54" 804 | "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" 805 | "checksum rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d127299b02abda51634f14025aec43ae87a7aa7a95202b6a868ec852607d1451" 806 | "checksum sample 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc0966ad788ec7289562643e05c611b7853e0618b7f9306aafd2fc727abfe168" 807 | "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" 808 | "checksum scrap 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04f3e5e5b3bd8d65b04de768fe0bdbd1e2da0831be9f117e1cc1d71785c9126c" 809 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 810 | "checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920" 811 | "checksum serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3525a779832b08693031b8ecfb0de81cd71cfd3812088fafe9a7496789572124" 812 | "checksum smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "312a7df010092e73d6bbaf141957e868d4f30efd2bfd9bb1028ad91abec58514" 813 | "checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa" 814 | "checksum stdweb 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef5430c8e36b713e13b48a9f709cc21e046723fe44ce34587b73a830203b533e" 815 | "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" 816 | "checksum syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2beff8ebc3658f07512a413866875adddd20f4fd47b2a4e6c9da65cd281baaea" 817 | "checksum tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47776f63b85777d984a50ce49d6b9e58826b6a3766a449fc95bc66cd5663c15b" 818 | "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" 819 | "checksum termios 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70226acdf12d182df757d9fb07c0257a1558ec48c8059f607d6b38145ce4e2fa" 820 | "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" 821 | "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" 822 | "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" 823 | "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" 824 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 825 | "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 826 | "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" 827 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" 828 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 829 | "checksum webm 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "42a860ee65db880db9709b62dd5ea898678260555daf3572e1fbb112ee954e35" 830 | "checksum webm-sys 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea73d1e3460cf2dac92b08f93be337fe0ede7600bd01cdcf8de00479f64f3cd7" 831 | "checksum which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e84a603e7e0b1ce1aa1ee2b109c7be00155ce52df5081590d1ffb93f4f515cb2" 832 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 833 | "checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" 834 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 835 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 836 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 837 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "srs" 3 | description = "WebM screen recorder." 4 | repository = "https://github.com/quadrupleslap/srs" 5 | authors = ["Ram Kaniyur "] 6 | license = "MIT" 7 | version = "0.2.0" 8 | 9 | [dependencies] 10 | cpal = "0.8" 11 | crossbeam-channel = "0.2" 12 | docopt = "1" 13 | libvpx-native-sys = "4" 14 | opus = "0.2" 15 | quest = "0.2" 16 | sample = "0.10" 17 | scrap = "0.5" 18 | serde = "1" 19 | serde_derive = "1" 20 | webm = "1" 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Screen Recording Software 2 | 3 | `srs` records your screen. 4 | 5 | ## Installation 6 | 7 | ```sh 8 | cargo install srs 9 | ``` 10 | 11 | Don't forget to install `libvpx` and `libopus`. 12 | 13 | ## Video Format 14 | 15 | The video is stored as a WebM file, using the VP9 and Opus codecs. 16 | 17 | ## Contributing 18 | 19 | All contributions are (obviously) appreciated. 20 | -------------------------------------------------------------------------------- /src/convert.rs: -------------------------------------------------------------------------------- 1 | pub fn argb_to_i420(width: usize, height: usize, src: &[u8], dest: &mut Vec) { 2 | let stride = src.len() / height; 3 | 4 | dest.clear(); 5 | 6 | for y in 0..height { 7 | for x in 0..width { 8 | let o = y * stride + 4 * x; 9 | 10 | let b = src[o] as i32; 11 | let g = src[o + 1] as i32; 12 | let r = src[o + 2] as i32; 13 | 14 | let y = (66 * r + 129 * g + 25 * b + 128) / 256 + 16; 15 | dest.push(clamp(y)); 16 | } 17 | } 18 | 19 | for y in (0..height).step_by(2) { 20 | for x in (0..width).step_by(2) { 21 | let o = y * stride + 4 * x; 22 | 23 | let b = src[o] as i32; 24 | let g = src[o + 1] as i32; 25 | let r = src[o + 2] as i32; 26 | 27 | let u = (-38 * r - 74 * g + 112 * b + 128) / 256 + 128; 28 | dest.push(clamp(u)); 29 | } 30 | } 31 | 32 | for y in (0..height).step_by(2) { 33 | for x in (0..width).step_by(2) { 34 | let o = y * stride + 4 * x; 35 | 36 | let b = src[o] as i32; 37 | let g = src[o + 1] as i32; 38 | let r = src[o + 2] as i32; 39 | 40 | let v = (112 * r - 94 * g - 18 * b + 128) / 256 + 128; 41 | dest.push(clamp(v)); 42 | } 43 | } 44 | } 45 | 46 | fn clamp(x: i32) -> u8 { 47 | x.min(255).max(0) as u8 48 | } 49 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate serde_derive; 3 | 4 | extern crate cpal; 5 | extern crate crossbeam_channel as channel; 6 | extern crate docopt; 7 | extern crate opus; 8 | extern crate quest; 9 | extern crate sample; 10 | extern crate scrap; 11 | extern crate serde; 12 | extern crate vpx_sys; 13 | extern crate webm; 14 | 15 | mod convert; 16 | mod sound; 17 | mod vpx; 18 | 19 | use docopt::Docopt; 20 | use scrap::{Capturer, Display}; 21 | use std::fmt; 22 | use std::fs::{File, OpenOptions}; 23 | use std::path::PathBuf; 24 | use std::sync::atomic::{AtomicBool, Ordering}; 25 | use std::sync::Arc; 26 | use std::time::{Duration, Instant}; 27 | use std::{io, thread}; 28 | use webm::mux; 29 | use webm::mux::Track; 30 | 31 | const USAGE: &'static str = " 32 | Simple WebM screen capture. 33 | 34 | Usage: 35 | srs [--time=] [--fps=] [--bv=] [--ba=] 36 | srs (-h | --help) 37 | 38 | Options: 39 | -h --help Show this screen. 40 | --time= Recording duration in seconds. 41 | --fps= Frames per second [default: 30]. 42 | --bv= Video bitrate in kilobits per second [default: 5000]. 43 | --ba= Audio bitrate in kilobits per second [default: 96]. 44 | "; 45 | 46 | #[derive(Debug, Deserialize)] 47 | struct Args { 48 | arg_path: PathBuf, 49 | flag_time: Option, 50 | flag_fps: u64, 51 | flag_bv: u32, 52 | flag_ba: u32, 53 | } 54 | 55 | fn main() -> io::Result<()> { 56 | let args: Args = Docopt::new(USAGE) 57 | .and_then(|d| d.deserialize()) 58 | .unwrap_or_else(|e| e.exit()); 59 | 60 | let duration = args.flag_time.map(Duration::from_secs); 61 | 62 | // Get the display. 63 | 64 | let displays = Display::all()?; 65 | 66 | let i = if displays.is_empty() { 67 | error("No displays found."); 68 | return Ok(()); 69 | } else if displays.len() == 1 { 70 | 0 71 | } else { 72 | let names: Vec<_> = displays 73 | .iter() 74 | .enumerate() 75 | .map( 76 | |(i, display)| format!("Display {} [{}x{}]", i, display.width(), display.height(),), 77 | ) 78 | .collect(); 79 | 80 | quest::ask("Which display?\n")?; 81 | let i = quest::choose(Default::default(), &names)?; 82 | println!(); 83 | 84 | i 85 | }; 86 | 87 | let display = displays.into_iter().nth(i).unwrap(); 88 | 89 | // Get the microphone. 90 | 91 | let mics: Vec<_> = cpal::input_devices().collect(); 92 | let mic = if mics.is_empty() { 93 | None 94 | } else { 95 | let mut names = vec!["None".into()]; 96 | names.extend(mics.iter().map(|m| m.name())); 97 | 98 | quest::ask("Which audio source?\n")?; 99 | let i = quest::choose(Default::default(), &names)?; 100 | println!(); 101 | 102 | if i == 0 { 103 | None 104 | } else { 105 | Some(mics.into_iter().nth(i - 1).unwrap()) 106 | } 107 | }; 108 | 109 | // Setup the recorder. 110 | 111 | let mut capturer = Capturer::new(display)?; 112 | let width = capturer.width() as u32; 113 | let height = capturer.height() as u32; 114 | 115 | // Setup the multiplexer. 116 | 117 | let out = match { 118 | OpenOptions::new() 119 | .write(true) 120 | .create_new(true) 121 | .open(&args.arg_path) 122 | } { 123 | Ok(file) => file, 124 | Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => { 125 | if loop { 126 | quest::ask("Overwrite the existing file? [y/N] ")?; 127 | if let Some(b) = quest::yesno(false)? { 128 | break b; 129 | } 130 | } { 131 | File::create(&args.arg_path)? 132 | } else { 133 | return Ok(()); 134 | } 135 | } 136 | Err(e) => return Err(e.into()), 137 | }; 138 | 139 | let mut webm = 140 | mux::Segment::new(mux::Writer::new(out)).expect("Could not initialize the multiplexer."); 141 | 142 | let mut vt = webm.add_video_track(width, height, None, mux::VideoCodecId::VP9); 143 | 144 | // Setup the encoder. 145 | 146 | let mut vpx = vpx::Encoder::new(vpx::Config { 147 | width: width, 148 | height: height, 149 | timebase: [1, 1000], 150 | bitrate: args.flag_bv, 151 | }); 152 | 153 | // Start recording. 154 | 155 | let start = Instant::now(); 156 | let stop = Arc::new(AtomicBool::new(false)); 157 | 158 | if let Some(mic) = mic { 159 | if let Err(e) = sound::run(stop.clone(), mic, &mut webm, args.flag_ba) { 160 | error(e); 161 | } 162 | } 163 | 164 | thread::spawn({ 165 | let stop = stop.clone(); 166 | move || { 167 | let _ = quest::ask("Recording! Press ⏎ to stop."); 168 | let _ = quest::text(); 169 | stop.store(true, Ordering::Release); 170 | } 171 | }); 172 | 173 | let spf = Duration::from_nanos(1_000_000_000 / args.flag_fps); 174 | let mut yuv = Vec::new(); 175 | 176 | while !stop.load(Ordering::Acquire) { 177 | let now = Instant::now(); 178 | let time = now - start; 179 | 180 | if Some(true) == duration.map(|d| time > d) { 181 | break; 182 | } 183 | 184 | match capturer.frame() { 185 | Ok(frame) => { 186 | let ms = time.as_secs() * 1000 + time.subsec_millis() as u64; 187 | 188 | convert::argb_to_i420(width as usize, height as usize, &frame, &mut yuv); 189 | 190 | for frame in vpx.encode(ms as i64, &yuv) { 191 | vt.add_frame(frame.data, frame.pts as u64 * 1_000_000, frame.key); 192 | } 193 | } 194 | Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { 195 | // Wait. 196 | } 197 | Err(e) => { 198 | println!("{}", e); 199 | break; 200 | } 201 | } 202 | 203 | let dt = now.elapsed(); 204 | if dt < spf { 205 | thread::sleep(spf - dt); 206 | } 207 | } 208 | 209 | // End things. 210 | 211 | let mut frames = vpx.finish(); 212 | while let Some(frame) = frames.next() { 213 | vt.add_frame(frame.data, frame.pts as u64 * 1_000_000, frame.key); 214 | } 215 | 216 | let _ = webm.finalize(None); 217 | 218 | Ok(()) 219 | } 220 | 221 | fn error(s: S) { 222 | println!("\u{1B}[1;31m{}\u{1B}[0m", s); 223 | } 224 | -------------------------------------------------------------------------------- /src/sound.rs: -------------------------------------------------------------------------------- 1 | use cpal; 2 | use opus; 3 | use sample::Signal; 4 | use sample::{interpolate, signal}; 5 | use std::sync::atomic::{AtomicBool, Ordering}; 6 | use std::sync::Arc; 7 | use std::{error, fmt, thread}; 8 | use webm::mux; 9 | use webm::mux::Track; 10 | 11 | const SAMPLE_RATE: usize = 48_000; 12 | const FRAME_SIZE: usize = 960; 13 | const MAX_PACKET: usize = 4000; 14 | 15 | pub fn run( 16 | stop: Arc, 17 | mic: cpal::Device, 18 | webm: &mut mux::Segment, 19 | bitrate: u32, 20 | ) -> Result<(), Error> { 21 | let fmt = mic.default_input_format()?; 22 | 23 | let mut opus = SendEncoder(opus::Encoder::new( 24 | SAMPLE_RATE as _, 25 | match fmt.channels { 26 | 1 => opus::Channels::Mono, 27 | 2 => opus::Channels::Stereo, 28 | x => return Err(Error::BadChannelCount(x)), 29 | }, 30 | opus::Application::Audio, 31 | )?); 32 | 33 | opus.set_bitrate(opus::Bitrate::Bits((bitrate * 1000) as _))?; 34 | 35 | let mut at = webm.add_audio_track( 36 | SAMPLE_RATE as _, 37 | fmt.channels as _, 38 | None, 39 | mux::AudioCodecId::Opus, 40 | ); 41 | 42 | let evs = cpal::EventLoop::new(); 43 | let id = evs.build_input_stream(&mic, &fmt)?; 44 | evs.play_stream(id); 45 | 46 | macro_rules! main {{ 47 | $b:ident; 48 | $d:ident => $s:expr; 49 | ($i:ident, $o:ident) => $w:expr; 50 | } => { 51 | if fmt.channels == 1 { 52 | main! { $b; 1; $d => $s; ($i, $o) => $w; } 53 | } else { 54 | main! { $b; 2; $d => $s; ($i, $o) => $w; } 55 | } 56 | }; { 57 | $buffer:ident; 58 | $chan:expr; 59 | $data:ident => $signal:expr; 60 | ($i:ident, $o:ident) => $write:expr; 61 | } => { 62 | let target = FRAME_SIZE * $chan as usize; 63 | let mut $i = Vec::new(); 64 | let mut $o = [0u8; MAX_PACKET]; 65 | let mut p = interpolate::Linear::new([0 as _; $chan], [0 as _; $chan]); 66 | let mut time = 0; //TODO: Won't this drift? 67 | 68 | evs.run(move |_, data| { 69 | if stop.load(Ordering::Acquire) { 70 | thread::park(); //TODO: End the thread. 71 | return; 72 | } 73 | 74 | let $data = match data { 75 | cpal::StreamData::Input { 76 | buffer: cpal::UnknownTypeInputBuffer::$buffer(buf), 77 | } => buf, 78 | _ => return, 79 | }; 80 | 81 | let s2 = interpolate::Converter::from_hz_to_hz( 82 | signal::from_interleaved_samples_iter::<_, [_; $chan]>($signal), 83 | BorrowedInterpolator(&mut p), 84 | fmt.sample_rate.0 as _, 85 | SAMPLE_RATE as _, 86 | ); 87 | 88 | for frame in s2.until_exhausted() { 89 | $i.extend_from_slice(&frame); 90 | if $i.len() >= target { 91 | let n = $write; 92 | at.add_frame(&$o[..n], time, true); //TODO: Which frames are key? 93 | $i.clear(); 94 | time += 20_000_000; 95 | } 96 | } 97 | }); 98 | }} 99 | 100 | thread::spawn(move || match fmt.data_type { 101 | cpal::SampleFormat::I16 => { 102 | main! { 103 | I16; 104 | data => data.iter().cloned(); 105 | (i, o) => opus.encode(&i, &mut o).unwrap(); 106 | } 107 | } 108 | cpal::SampleFormat::U16 => { 109 | main! { 110 | U16; 111 | data => data.iter().map(cpal::Sample::to_i16); 112 | (i, o) => opus.encode(&i, &mut o).unwrap(); 113 | } 114 | } 115 | cpal::SampleFormat::F32 => { 116 | main! { 117 | F32; 118 | data => data.iter().cloned(); 119 | (i, o) => opus.encode_float(&i, &mut o).unwrap(); 120 | } 121 | } 122 | }); 123 | 124 | Ok(()) 125 | } 126 | 127 | #[derive(Debug)] 128 | pub enum Error { 129 | Opus(opus::Error), 130 | StreamCreation(cpal::CreationError), 131 | DefaultFormat(cpal::DefaultFormatError), 132 | BadChannelCount(u16), 133 | } 134 | 135 | impl From for Error { 136 | fn from(e: opus::Error) -> Self { 137 | Error::Opus(e) 138 | } 139 | } 140 | 141 | impl From for Error { 142 | fn from(e: cpal::DefaultFormatError) -> Self { 143 | Error::DefaultFormat(e) 144 | } 145 | } 146 | 147 | impl From for Error { 148 | fn from(e: cpal::CreationError) -> Self { 149 | Error::StreamCreation(e) 150 | } 151 | } 152 | 153 | impl fmt::Display for Error { 154 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 155 | match self { 156 | Error::Opus(e) => e.fmt(f), 157 | Error::StreamCreation(e) => e.fmt(f), 158 | Error::DefaultFormat(e) => e.fmt(f), 159 | Error::BadChannelCount(n) => { 160 | write!(f, "Expected 1 or 2 channels, but found {} channels.", n,) 161 | } 162 | } 163 | } 164 | } 165 | 166 | impl error::Error for Error {} 167 | 168 | //TODO: Remove this. 169 | struct BorrowedInterpolator<'a, I: 'a>(&'a mut I); 170 | 171 | impl<'a, I> interpolate::Interpolator for BorrowedInterpolator<'a, I> 172 | where 173 | I: interpolate::Interpolator, 174 | { 175 | type Frame = I::Frame; 176 | 177 | fn interpolate(&self, x: f64) -> Self::Frame { 178 | self.0.interpolate(x) 179 | } 180 | 181 | fn next_source_frame(&mut self, s: Self::Frame) { 182 | self.0.next_source_frame(s) 183 | } 184 | } 185 | 186 | //TODO: Remove this. 187 | struct SendEncoder(pub opus::Encoder); 188 | unsafe impl Send for SendEncoder {} 189 | impl ::std::ops::Deref for SendEncoder { 190 | type Target = opus::Encoder; 191 | fn deref(&self) -> &Self::Target { 192 | &self.0 193 | } 194 | } 195 | impl ::std::ops::DerefMut for SendEncoder { 196 | fn deref_mut(&mut self) -> &mut Self::Target { 197 | &mut self.0 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/vpx.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::{c_int, c_uint, c_ulong}; 2 | use std::{ptr, slice}; 3 | use vpx_sys::vp8e_enc_control_id::*; 4 | use vpx_sys::vpx_codec_cx_pkt_kind::VPX_CODEC_CX_FRAME_PKT; 5 | use vpx_sys::*; 6 | 7 | const ABI_VERSION: c_int = 14; 8 | const DEADLINE: c_ulong = 1; 9 | 10 | pub struct Encoder { 11 | ctx: vpx_codec_ctx_t, 12 | width: usize, 13 | height: usize, 14 | } 15 | 16 | impl Encoder { 17 | pub fn new(config: Config) -> Self { 18 | let i = unsafe { vpx_codec_vp9_cx() }; 19 | 20 | assert!(config.width % 2 == 0); 21 | assert!(config.height % 2 == 0); 22 | 23 | let mut c = Default::default(); 24 | unsafe { vpx_codec_enc_config_default(i, &mut c, 0) }; //TODO: Error. 25 | 26 | c.g_w = config.width; 27 | c.g_h = config.height; 28 | c.g_timebase.num = config.timebase[0]; 29 | c.g_timebase.den = config.timebase[1]; 30 | c.rc_target_bitrate = config.bitrate; 31 | 32 | c.g_threads = 8; 33 | c.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT; 34 | 35 | let mut ctx = Default::default(); 36 | unsafe { 37 | vpx_codec_enc_init_ver(&mut ctx, i, &c, 0, ABI_VERSION); //TODO: Error. 38 | vpx_codec_control_(&mut ctx, VP8E_SET_CPUUSED as _, 6 as c_int); //TODO: Error. 39 | vpx_codec_control_(&mut ctx, VP9E_SET_ROW_MT as _, 1 as c_int); //TODO: Error. 40 | } 41 | 42 | Self { 43 | ctx, 44 | width: config.width as usize, 45 | height: config.height as usize, 46 | } 47 | } 48 | 49 | pub fn encode(&mut self, pts: i64, data: &[u8]) -> Packets { 50 | assert!(2 * data.len() >= 3 * self.width * self.height); 51 | 52 | let mut image = Default::default(); 53 | unsafe { 54 | vpx_img_wrap( 55 | &mut image, 56 | vpx_img_fmt::VPX_IMG_FMT_I420, 57 | self.width as _, 58 | self.height as _, 59 | 1, 60 | data.as_ptr() as _, 61 | ); 62 | } 63 | 64 | unsafe { 65 | vpx_codec_encode( 66 | &mut self.ctx, 67 | &image, 68 | pts, 69 | 1, // Alignment 70 | 0, // Flags 71 | DEADLINE, 72 | ); //TODO: Error. 73 | } 74 | 75 | Packets { 76 | ctx: &mut self.ctx, 77 | iter: ptr::null(), 78 | } 79 | } 80 | 81 | pub fn finish(mut self) -> Finish { 82 | unsafe { 83 | vpx_codec_encode( 84 | &mut self.ctx, 85 | ptr::null(), 86 | -1, // PTS 87 | 1, // Alignment 88 | 0, // Flags 89 | DEADLINE, 90 | ); //TODO: Error. 91 | } 92 | 93 | Finish { 94 | enc: self, 95 | iter: ptr::null(), 96 | } 97 | } 98 | } 99 | 100 | impl Drop for Encoder { 101 | fn drop(&mut self) { 102 | unsafe { 103 | let _ = vpx_codec_destroy(&mut self.ctx); 104 | } 105 | } 106 | } 107 | 108 | #[derive(Clone, Copy, Debug)] 109 | pub struct Frame<'a> { 110 | /// Compressed data. 111 | pub data: &'a [u8], 112 | /// Whether the frame is a keyframe. 113 | pub key: bool, 114 | /// Presentation timestamp (in timebase units). 115 | pub pts: i64, 116 | } 117 | 118 | #[derive(Clone, Copy, Debug)] 119 | pub struct Config { 120 | /// The width (in pixels). 121 | pub width: c_uint, 122 | /// The height (in pixels). 123 | pub height: c_uint, 124 | /// The timebase (in seconds). 125 | pub timebase: [c_int; 2], 126 | /// The target bitrate (in kilobits per second). 127 | pub bitrate: c_uint, 128 | } 129 | 130 | pub struct Packets<'a> { 131 | ctx: &'a mut vpx_codec_ctx_t, 132 | iter: vpx_codec_iter_t, 133 | } 134 | 135 | impl<'a> Iterator for Packets<'a> { 136 | type Item = Frame<'a>; 137 | fn next(&mut self) -> Option { 138 | loop { 139 | unsafe { 140 | let pkt = vpx_codec_get_cx_data(self.ctx, &mut self.iter); 141 | 142 | if pkt.is_null() { 143 | return None; 144 | } else if (*pkt).kind == VPX_CODEC_CX_FRAME_PKT { 145 | let f = &(*pkt).data.frame; 146 | return Some(Frame { 147 | data: slice::from_raw_parts(f.buf as _, f.sz), 148 | key: (f.flags & VPX_FRAME_IS_KEY) != 0, 149 | pts: f.pts, 150 | }); 151 | } else { 152 | // Ignore the packet. 153 | } 154 | } 155 | } 156 | } 157 | } 158 | 159 | pub struct Finish { 160 | enc: Encoder, 161 | iter: vpx_codec_iter_t, 162 | } 163 | 164 | impl Finish { 165 | pub fn next(&mut self) -> Option { 166 | let mut tmp = Packets { 167 | ctx: &mut self.enc.ctx, 168 | iter: self.iter, 169 | }; 170 | 171 | if let Some(packet) = tmp.next() { 172 | self.iter = tmp.iter; 173 | Some(packet) 174 | } else { 175 | unsafe { 176 | vpx_codec_encode( 177 | tmp.ctx, 178 | ptr::null(), 179 | -1, // PTS 180 | 1, // Alignment 181 | 0, // Flags 182 | DEADLINE, 183 | ); //TODO: Error. 184 | } 185 | 186 | tmp.iter = ptr::null(); 187 | if let Some(packet) = tmp.next() { 188 | self.iter = tmp.iter; 189 | Some(packet) 190 | } else { 191 | None 192 | } 193 | } 194 | } 195 | } 196 | --------------------------------------------------------------------------------