kricker

moho_2_time_remap.jsx

Dec 18th, 2012
732
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.86 KB | None | 0 0
  1. // This script reads a user specified MOHO.dat text file and
  2. // creates a time remapped layer with the frame values from the MOHO.dat file.
  3. // The new comp is called "my MOHO comp"
  4. // Developed and tested only on After Effects CS3, no gaurantee it will work on other versions.
  5. //
  6. // By Atom
  7. // 04/11/2012
  8. //
  9. // This script is released under the CC-BY license.
  10. // http://creativecommons.org/licenses/by/3.0/
  11. // Because it is not practical for the user to credit me in all occasions,
  12. // I allow users to create content with this script without crediting Atom directly in their published work,
  13. // however, any derived script modifications or distributions of this script must contain this comment and credit Atom.
  14. // This script can not be bundled or added to books or electronic publishing without consulting Atom first.
  15.  
  16. {
  17. // Begin small function library.
  18. function isNumeric(val) {
  19. if (isNaN(parseFloat(val))) {
  20. return false;
  21. }
  22. return true
  23. }
  24. function returnFrameFromItem(passedItem) {
  25. result = -1;
  26. lst = passedItem.split(' ');
  27. if (lst.length > 0) {
  28. if (isNumeric(lst[0]) == true) {
  29. result = parseInt(lst[0]);
  30. }
  31. }
  32. return result;
  33. }
  34. function returnPhonemeFromItem(passedItem) {
  35. result = "";
  36. lst = passedItem.split(' ');
  37. if (lst.length > 0) {
  38. if (isNumeric(lst[0]) == true) {
  39. result = lst[1];
  40. }
  41. }
  42. return result;
  43. }
  44. function returnPhonemeForFrame (passedList, passedFrame) {
  45. result = "";
  46. l = passedList.length;
  47. for (n = 0; n <l; n++) {
  48. item = passedList[n];
  49. f = returnFrameFromItem(item);
  50. if (f == passedFrame) {
  51. result = returnPhonemeFromItem(item);
  52. break;
  53. }
  54. }
  55. return result;
  56. }
  57. function returnTimeRemapFrameFromPhoneme(passedItem) {
  58. // NOTE: This assumes you have a frame in a comp for each phoneme listed in this order (i.e. alphabetically).
  59. switch(passedItem) {
  60. case 'AI':
  61. f = 0;
  62. break;
  63. case 'E':
  64. f = 1;
  65. break;
  66. case 'etc':
  67. f = 2;
  68. break;
  69. case 'FV':
  70. f = 3;
  71. break;
  72. case 'L':
  73. f = 4;
  74. break;
  75. case 'MBP':
  76. f = 5;
  77. break;
  78. case 'O':
  79. f = 6;
  80. break;
  81. case 'rest':
  82. f = 7;
  83. break;
  84. case 'U':
  85. f = 8;
  86. break;
  87. case 'WQ':
  88. f = 9;
  89. break;
  90. case 'TH':
  91. // Not part of preston-blair default.
  92. // This part of preston-blair extended.
  93. f = 10;
  94. break;
  95. default:
  96. f = -1;
  97. break;
  98. }
  99. return f;
  100. }
  101. // End small function library.
  102.  
  103. // Create undo group
  104. app.beginUndoGroup("Create Lip-Synch From MOHO File");
  105.  
  106. // Detect the selected comp in the project bin.
  107. var projectSelection = app.project.selection;
  108. pl = projectSelection.length;
  109. if (pl == 1)
  110. {
  111. // create project if necessary
  112. var proj = app.project;
  113. if(!proj) proj = app.newProject();
  114.  
  115. // create new comp named 'my MOHO comp'
  116. var compW = 1280; // comp width
  117. var compH = 720; // comp height
  118. var compL = 30; // comp length (seconds)
  119. var compRate = 30; // comp frame rate (24fps is the default fps for Papagoya, adjust as needed.)
  120. var compBG = [48/255,63/255,84/255] // comp background color
  121.  
  122. var myItemCollection = app.project.items;
  123. var myComp = myItemCollection.addComp('my MOHO comp',compW,compH,1,compL,compRate);
  124. myComp.bgColor = compBG;
  125.  
  126. // Prompt user to select text file
  127. var myFile = File.openDialog("");
  128. if (myFile != null)
  129. {
  130. // open file
  131. var fileOK = myFile.open("");
  132. if (fileOK)
  133. {
  134. for (i=0; i < pl; i++)
  135. {
  136. //Add comp
  137. if(projectSelection[i] instanceof CompItem) // Test to be sure it is a comp.
  138. {
  139. thisLayer = myComp.layers.add(projectSelection[i]); // Add the selected comp as a layer to the MOHO comp.
  140. thisLayer.timeRemapEnabled = true; // Enable time remapping.
  141. myRemap= thisLayer.property("Time Remap");
  142. // By default two keyframes are added when time remap is enabled.
  143. // Let's remove the first one now, effectively making this a freeze frame.
  144. myRemap.removeKey(1);
  145. }
  146. }
  147. // Read the text file to get the frame numbers to generate keyframes on.
  148. var s = "";
  149. var lastValue = -1;
  150. var lastLine = "";
  151. var lstLines = [];
  152. var n = 0;
  153. var l = 0;
  154. var f = 0;
  155. while (!myFile.eof)
  156. {
  157. text = myFile.readln();
  158. if (text != lastLine) {
  159. if (text != undefined)
  160. {
  161. f = returnFrameFromItem(text);
  162. if (f != -1) {
  163. // Only add valid lines of text to the list.
  164. lstLines.push(text);
  165. lastLine = text;
  166. n = n + 1;
  167. }
  168. }
  169. }
  170. }
  171. // Close the file.
  172. myFile.close();
  173.  
  174. // Get the last frame number that has a phoneme.
  175. l = lstLines.length;
  176. last_frame = returnFrameFromItem(lstLines[l-1]);
  177. if (last_frame != -1) {
  178. first_frame = returnFrameFromItem (lstLines[0]);
  179. if (first_frame != -1)
  180. {
  181. cur_frame = first_frame;
  182. // Create a time remap keyframe for every frame.
  183. for (i=first_frame;i<last_frame;i++)
  184. {
  185. cur_phoneme = returnPhonemeForFrame(lstLines,i);
  186. if (cur_phoneme != "")
  187. {
  188. if (isNumeric(cur_phoneme) == false)
  189. {
  190. // Fetch the frame we should be using based upon the phoneme.
  191. cur_frame = returnTimeRemapFrameFromPhoneme(cur_phoneme);
  192. if (cur_frame == -1)
  193. {
  194. // Ok, what is wrong...?
  195. s = parseInt(i) + ", " + parseInt(first_frame) + ", " + parseInt(last_frame) + ", " + parseInt(cur_frame) + ", " + cur_phoneme;
  196. alert("Bad phoneme [" + s + "] encountered.");
  197. }
  198. }
  199. }
  200. frame_as_time = i/compRate;
  201. frame_remap_as_time = cur_frame/compRate;
  202. myRemap.setValueAtTime(frame_as_time,frame_remap_as_time);
  203. if (i == first_frame) {
  204. // Remove the final keyframe that was generated when time remap was enabled.
  205. myRemap.removeKey(1);
  206. }
  207. }
  208. // Lets go ahead and extend our outpoint to the last frame we detected in our MOHO.dat file.
  209. thisLayer.outPoint = last_frame/compRate;
  210. } else {
  211. alert("First frame is -1.");
  212. }
  213. } else {
  214. alert("Last frame is -1.");
  215. }
  216. } else {
  217. alert("Problem with MOHO.dat file..?");
  218. }
  219. } else {
  220. s = "User canceled operation.";
  221. }
  222. } else {
  223. alert("Select a single composition with your phoneme mouth images\nbefore you run this script.");
  224. }
  225. app.endUndoGroup();
  226. }
Advertisement
Add Comment
Please, Sign In to add comment