-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmakeMulticam.js
180 lines (152 loc) · 6.31 KB
/
makeMulticam.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
function makeMulticam(xmlData) {
// get highest ref number
let highestId = 0
xmlData.querySelectorAll('*').forEach((element) => {
if (element.id.startsWith('r')) {
var num = parseInt(element.id.split('r')[1])
if (num > highestId) {
highestId = num
}
}
})
// for each project in the xml
var multicams = []
for (let i = 0; i < xmlData.getElementsByTagName('project').length; i++) {
var spine = xmlData.getElementsByTagName('project')[i].getElementsByTagName('spine')[0]
// for each clip in the project
assetClipList = []
// make list of spine children
var assetClips = []
for (let j = 0; j < spine.children.length; j++) {
if (spine.children[j].tagName == 'asset-clip') {
assetClips.push(spine.children[j])
}
}
for (let j = 0; j < assetClips.length; j++) {
var assetClip = assetClips[j]
assetClipList.push(assetClip)
var ref = assetClip.getAttribute('ref')
// find asset in resources and add multicam
for (let k = 0; k < xmlData.getElementsByTagName('resources')[0].getElementsByTagName('asset').length; k++) {
var asset = xmlData.getElementsByTagName('resources')[0].getElementsByTagName('asset')[k]
if (asset.getAttribute('id') == ref) {
if (multicams.indexOf(ref) == -1) {
// create media in resources
var media = xmlData.createElement('media')
media.setAttribute('id', 'r' + (highestId + 1))
highestId = highestId + 1
media.setAttribute('name', asset.getAttribute('name'))
xmlData.getElementsByTagName('resources')[0].appendChild(media)
// create multicam in media
var multicam = xmlData.createElement('multicam')
multicam.setAttribute('format', asset.getAttribute('format'))
multicam.setAttribute('tcStart', asset.getAttribute('start'))
multicam.setAttribute('tcFormat', 'NDF')
media.appendChild(multicam)
// create A angle in multicam
var angle = xmlData.createElement('mc-angle')
angle.setAttribute('name', 'A')
angle.setAttribute('angleID', asset.getAttribute('name') + asset.getAttribute('id') + 'A')
multicam.appendChild(angle)
// create asset-clip in A angle
var assetClipinAngle = xmlData.createElement('asset-clip')
assetClipinAngle.setAttribute('ref', asset.getAttribute('id'))
assetClipinAngle.setAttribute('offset', '0s')
assetClipinAngle.setAttribute('name', asset.getAttribute('name'))
assetClipinAngle.setAttribute('duration', asset.getAttribute('duration'))
assetClipinAngle.setAttribute('format', asset.getAttribute('format'))
assetClipinAngle.setAttribute('tcFormat', 'NDF')
assetClipinAngle.setAttribute('audioRole', 'dialogue')
angle.appendChild(assetClipinAngle)
// create B angle in multicam
var angle = xmlData.createElement('mc-angle')
angle.setAttribute('name', 'B')
angle.setAttribute('angleID', asset.getAttribute('name') + asset.getAttribute('id') + 'B')
multicam.appendChild(angle)
multicams.push(ref)
}
// create mc-clip based on asset-clip
var mcClip = xmlData.createElement('mc-clip')
mcClip.setAttribute('ref', 'r' + (highestId))
mcClip.setAttribute('offset', assetClip.getAttribute('offset'))
mcClip.setAttribute('name', assetClip.getAttribute('name'))
mcClip.setAttribute('duration', assetClip.getAttribute('duration'))
mcClip.setAttribute('start', assetClip.getAttribute('start'))
spine.insertBefore(mcClip, assetClip);
mcClip.innerHTML = assetClip.innerHTML
// add mc-source to mc-clip
var mcSource = xmlData.createElement('mc-source')
mcSource.setAttribute('angleID', asset.getAttribute('name') + asset.getAttribute('id') + 'A')
mcSource.setAttribute('srcEnable', "all")
mcClip.insertBefore(mcSource, mcClip.children[0]);
// if there is an element in mcClip called 'adjust-'volume', move it to the front of mcClip children
if (mcClip.getElementsByTagName('adjust-volume').length > 0) {
var adjustVolume = mcClip.getElementsByTagName('adjust-volume')[0]
mcClip.removeChild(adjustVolume)
mcClip.insertBefore(adjustVolume, mcClip.children[0])
}
break
}
}
}
for (let k = 0; k < assetClipList.length; k++) {
assetClipList[k].remove()
}
// make list of parsererror elements
var parsererrorList = []
for (let k = 0; k < xmlData.getElementsByTagName('parsererror').length; k++) {
parsererrorList.push(xmlData.getElementsByTagName('parsererror')[k])
}
// remove parsererror elements
for (let k = 0; k < parsererrorList.length; k++) {
parsererrorList[k].remove()
}
}
xmlDataString = new XMLSerializer().serializeToString(xmlData.documentElement);
console.log(xmlDataString)
download('made_multicam.fcpxml', xmlDataString)
}
document.querySelectorAll(".drop-zone__input").forEach((inputElement) => {
const dropZoneElement = inputElement.closest(".drop-zone");
dropZoneElement.addEventListener("dragover", (e) => {
e.preventDefault();
dropZoneElement.classList.add("drop-zone--over");
});
["dragleave", "dragend"].forEach((type) => {
dropZoneElement.addEventListener(type, (e) => {
dropZoneElement.classList.remove("drop-zone--over");
});
});
dropZoneElement.addEventListener("drop", (e) => {
e.preventDefault();
parser = new DOMParser();
if (e.dataTransfer.files.length) {
inputElement.files = e.dataTransfer.files;
var file = e.dataTransfer.files[0]
let reader = new FileReader();
reader.readAsText(file);
reader.onload = function () {
// if reader.result starts with <!DOCTYPE fcpxml>, remove it
var text = reader.result
if (reader.result.startsWith('<!DOCTYPE fcpxml>')) {
text = reader.result.split('<!DOCTYPE fcpxml>')[1]
}
xmlData = parser.parseFromString(text, "text/xml")
makeMulticam(xmlData)
}
} else {
var xmlData = parser.parseFromString(e.dataTransfer.getData("text/plain"), "text/xml")
makeMulticam(xmlData)
}
dropZoneElement.classList.remove("drop-zone--over");
});
});