Turn audio into a shareable video. forked from nypublicradio/audiogram

preview.js 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. var d3 = require("d3"),
  2. audio = require("./audio.js"),
  3. video = require("./video.js"),
  4. minimap = require("./minimap.js"),
  5. getWaveform = require("./waveform.js");
  6. var context = d3.select("canvas").node().getContext("2d");
  7. var renderer = require("../renderer/")(context);
  8. var theme,
  9. caption,
  10. file,
  11. selection;
  12. function _file(_) {
  13. return arguments.length ? (file = _) : file;
  14. }
  15. function _theme(_) {
  16. return arguments.length ? (theme = _, redraw()) : theme;
  17. }
  18. function _caption(_) {
  19. return arguments.length ? (caption = _, redraw()) : caption;
  20. }
  21. function _selection(_) {
  22. return arguments.length ? (selection = _) : selection;
  23. }
  24. minimap.onBrush(function(extent){
  25. var duration = audio.duration();
  26. selection = {
  27. duration: duration * (extent[1] - extent[0]),
  28. start: extent[0] ? extent[0] * duration : null,
  29. end: extent[1] < 1 ? extent[1] * duration : null
  30. };
  31. d3.select("#duration strong").text(Math.round(10 * selection.duration) / 10)
  32. .classed("red", theme && theme.maxDuration && theme.maxDuration < selection.duration);
  33. });
  34. // Resize video and preview canvas to maintain aspect ratio
  35. function resize(width, height) {
  36. var widthFactor = 640 / width,
  37. heightFactor = 360 / height,
  38. factor = Math.min(widthFactor, heightFactor);
  39. d3.select("canvas")
  40. .attr("width", factor * width)
  41. .attr("height", factor * height);
  42. d3.select("#canvas")
  43. .style("width", (factor * width) + "px");
  44. d3.select("video")
  45. .attr("height", widthFactor * height);
  46. d3.select("#video")
  47. .attr("height", (widthFactor * height) + "px");
  48. context.setTransform(factor, 0, 0, factor, 0, 0);
  49. }
  50. function redraw() {
  51. resize(theme.width, theme.height);
  52. video.kill();
  53. renderer.update(theme);
  54. renderer.caption = caption;
  55. renderer.backgroundImage = theme.backgroundImageFile || null;
  56. renderer.drawFrame(0);
  57. }
  58. function loadAudio(f, cb) {
  59. audio.pause();
  60. video.kill();
  61. d3.queue()
  62. .defer(getWaveform, f)
  63. .defer(audio.src, f)
  64. .await(function(err, data){
  65. if (err) {
  66. return cb(err);
  67. }
  68. file = f;
  69. minimap.redraw(data.peaks);
  70. cb(err);
  71. });
  72. }
  73. module.exports = {
  74. caption: _caption,
  75. theme: _theme,
  76. file: _file,
  77. selection: _selection,
  78. loadAudio: loadAudio
  79. };