ffmpeg_convert.agi 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. FFmpeg convert - the launcher
  3. Converts cluster:/demo.mp4 into cluster:/demo.webm as a cluster job.
  4. You never choose the node: the job asks for the "ffmpeg" capability and
  5. names its input file, and the scheduler picks a node that has ffmpeg,
  6. preferring one that already stores demo.mp4.
  7. Optional parameters, in the URL query or a form body:
  8. input default cluster:/demo.mp4
  9. output default cluster:/demo.webm
  10. A conversion can take a while, so this waits up to 30 seconds and then
  11. returns the job id. Watch the rest on System Settings > Cluster Jobs, or
  12. call cluster.jobs.status(id) later.
  13. Keep ffmpeg_convert.job.agi in the same folder as this file.
  14. */
  15. requirelib("cluster");
  16. //Read a request parameter. A script run as a Serverless endpoint gets the
  17. //request through getPara() (URL query) and postPara() (form body); a WebApp
  18. //backend script gets its POST fields as global variables instead.
  19. function requestParam(name) {
  20. var v = null;
  21. if (typeof getPara === "function") {
  22. v = getPara(name);
  23. }
  24. if ((v === null || v === "") && typeof postPara === "function") {
  25. v = postPara(name);
  26. }
  27. if (v === null || v === "") {
  28. var globalScope = (function () { return this; })();
  29. v = (typeof globalScope[name] === "string") ? globalScope[name] : "";
  30. }
  31. return v === null ? "" : String(v);
  32. }
  33. function main() {
  34. if (!cluster.inCluster()) {
  35. return { error: "This node is not part of a cluster. Create or join one in System Settings > Cluster Settings." };
  36. }
  37. var src = requestParam("input") || "cluster:/demo.mp4";
  38. var dst = requestParam("output") || "cluster:/demo.webm";
  39. var id = cluster.jobs.submit({
  40. name: "Convert " + src.split("/").pop() + " to " + dst.split(".").pop().toUpperCase(),
  41. script: "ffmpeg_convert.job.agi",
  42. args: { input: src, output: dst },
  43. inputs: [src], //prefer a node that already holds the video
  44. features: ["ffmpeg"], //only nodes with ffmpeg may take this job
  45. timeout: 3600
  46. });
  47. var rec;
  48. try {
  49. rec = cluster.jobs.wait(id, 30);
  50. } catch (e) {
  51. rec = cluster.jobs.status(id);
  52. return {
  53. job: id,
  54. status: rec.state.status,
  55. node: rec.state.node || "",
  56. //When nothing can take the job, reason says why (for example no node has ffmpeg)
  57. reason: rec.state.reason || "",
  58. note: "Still working. Follow it on System Settings > Cluster Jobs."
  59. };
  60. }
  61. if (rec.state.status !== "succeeded") {
  62. return { job: id, status: rec.state.status, error: rec.state.error || rec.state.reason || "" };
  63. }
  64. return rec.state.output;
  65. }
  66. sendJSONResp(JSON.stringify(main()));