Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
simple-editor
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Public
simple-editor
Commits
99176a92
Commit
99176a92
authored
Jan 11, 2022
by
Jonathan Thomas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Integrate Caption effect into Export API
parent
a91843ad
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
380 additions
and
5 deletions
+380
-5
Clips.vue
src/components/Clips.vue
+49
-3
caption.json
src/data/caption.json
+290
-0
index.js
src/store/index.js
+38
-0
Editor.vue
src/views/Editor.vue
+3
-2
No files found.
src/components/Clips.vue
View file @
99176a92
...
...
@@ -79,7 +79,7 @@
<div
class=
"modal-footer"
>
<button
type=
"button"
class=
"btn btn-secondary"
ref=
"Close"
data-bs-dismiss=
"modal"
>
Cancel
</button>
<a
v-if=
"current_export.output"
:href=
"current_export.output"
class=
"btn btn-info"
download
target=
"_blank"
>
Download
</a>
<button
v-if=
"!current_export.output"
type=
"button"
class=
"btn btn-primary"
@
click=
"startExport"
>
Export
</button>
<button
v-if=
"!current_export.output"
type=
"button"
class=
"btn btn-primary"
@
click=
"startExport"
:disabled=
"!current_export.output && current_export.progress > 0"
>
Export
</button>
<button
v-if=
"current_export.output"
type=
"button"
class=
"btn btn-primary"
@
click=
"startExport"
>
Export Again
</button>
</div>
</div>
...
...
@@ -90,6 +90,7 @@
<
script
>
import
{
mapActions
,
mapState
,
mapMutations
,
mapGetters
}
from
"vuex"
import
{
Modal
}
from
"bootstrap"
import
caption
from
"../data/caption.json"
export
default
{
name
:
"Clips.vue"
,
...
...
@@ -116,6 +117,51 @@ export default {
this
.
editClip
(
payload
)
},
async
startExport
()
{
// Search for existing caption effect (we can re-use it)
let
caption_results
=
this
.
effects
.
filter
(
e
=>
e
.
layer
==
999
&&
e
.
position
==
0.0
&&
e
.
type
==
'Caption'
)
let
effect_payload
=
{}
let
is_effect_new
=
false
// Get or create caption effect object
if
(
caption_results
.
length
==
1
)
{
effect_payload
=
caption_results
[
0
]
effect_payload
.
end
=
0
effect_payload
.
json
=
caption
}
else
{
is_effect_new
=
true
effect_payload
=
{
position
:
0
,
start
:
0
,
end
:
0
,
layer
:
999
,
project
:
this
.
project
.
url
,
title
:
'Caption'
,
type
:
'Caption'
,
json
:
caption
}
}
// Generate caption text (w/ timestamps)
caption
.
caption_text
=
""
for
(
let
clip
of
this
.
thumbnailedClips
)
{
if
(
clip
.
json
.
text
)
{
let
clip_right_edge
=
clip
.
position
+
(
clip
.
end
-
clip
.
start
)
if
(
clip_right_edge
>
effect_payload
.
end
)
{
effect_payload
.
end
=
clip_right_edge
}
let
start_timestamp
=
new
Date
(
clip
.
position
*
1000
).
toISOString
().
substr
(
11
,
12
)
let
end_timestamp
=
new
Date
((
clip
.
position
+
(
clip
.
end
-
clip
.
start
))
*
1000
).
toISOString
().
substr
(
11
,
12
)
caption
.
caption_text
+=
`
${
start_timestamp
}
-->
${
end_timestamp
}
\n
${
clip
.
json
.
text
}
\n\n`
}
}
// Save caption effect
if
(
is_effect_new
)
{
await
this
.
createEffect
(
effect_payload
)
}
else
{
await
this
.
updateEffect
(
effect_payload
)
}
// Create export
let
payload
=
{
"export_type"
:
"video"
,
"video_format"
:
"mp4"
,
...
...
@@ -164,12 +210,12 @@ export default {
let
myModal
=
new
Modal
(
this
.
$refs
.
exportModal
)
myModal
.
show
()
},
...
mapActions
([
'loadClips'
,
'createClip'
,
'deleteClip'
,
'editClip'
,
'moveClip'
,
'createExport'
]),
...
mapActions
([
'loadClips'
,
'createClip'
,
'deleteClip'
,
'editClip'
,
'moveClip'
,
'createExport'
,
'createEffect'
,
'updateEffect'
]),
...
mapMutations
(([
'setPreviewClip'
,
'setClips'
,
'setScrollToClip'
]))
},
computed
:
{
...
mapGetters
([
'totalClipDuration'
,
'thumbnailedClips'
]),
...
mapState
([
'clips'
,
'preview'
,
'scrollToClip'
,
'current_export'
])
...
mapState
([
'clips'
,
'preview'
,
'scrollToClip'
,
'current_export'
,
'effects'
])
},
watch
:
{
scrollToClip
()
{
...
...
src/data/caption.json
0 → 100644
View file @
99176a92
{
"background"
:
{
"alpha"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
255
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"blue"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"green"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"red"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
}
},
"background_alpha"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"background_corner"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
10
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"background_padding"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
20
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"caption_font"
:
"sans"
,
"caption_text"
:
"00:00:00:000 --> 00:10:00:000
\\
nEdit this caption with our caption editor"
,
"class_name"
:
"Caption"
,
"color"
:
{
"alpha"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
255
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"blue"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
255
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"green"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
255
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"red"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
255
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
}
},
"fade_in"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0.3499999940395355
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"fade_out"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0.3499999940395355
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"font_alpha"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
1
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"font_size"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
48
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"left"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0.25
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"name"
:
"Caption"
,
"right"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0.10000000149011612
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"stroke"
:
{
"alpha"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
255
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"blue"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
169
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"green"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
169
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"red"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
169
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
}
},
"stroke_width"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0.5
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"top"
:
{
"Points"
:
[
{
"co"
:
{
"X"
:
1
,
"Y"
:
0.75
},
"handle_type"
:
0
,
"interpolation"
:
0
}
]
},
"type"
:
"Caption"
}
\ No newline at end of file
src/store/index.js
View file @
99176a92
...
...
@@ -11,6 +11,7 @@ export default createStore({
errors
:
[],
uploads
:
[],
exports
:
[],
effects
:
[],
project
:
null
,
current_export
:
{
progress
:
0.0
},
user
:
null
,
...
...
@@ -61,6 +62,18 @@ export default createStore({
setProject
(
state
,
project
)
{
state
.
project
=
project
},
addEffect
(
state
,
effectObj
)
{
state
.
effects
.
push
(
effectObj
)
},
setEffects
(
state
,
effects
)
{
state
.
effects
=
effects
},
setEffect
(
state
,
effectObj
)
{
state
.
effects
=
[
...
state
.
effects
=
state
.
effects
.
filter
(
e
=>
e
.
id
!=
effectObj
.
id
),
effectObj
]
},
updateProjectThumbnail
(
state
,
payload
)
{
state
.
projects
=
[
...
state
.
projects
=
state
.
projects
.
filter
(
p
=>
p
.
id
!=
payload
.
obj
.
id
),
...
...
@@ -467,6 +480,31 @@ export default createStore({
commit
(
'addError'
,
err
.
response
.
data
)
}
},
async
loadEffects
({
commit
},
project_id
)
{
try
{
const
effects_response
=
await
instance
.
get
(
`projects/
${
project_id
}
/effects/`
)
commit
(
'setEffects'
,
effects_response
.
data
.
results
)
}
catch
(
err
)
{
commit
(
'addError'
,
err
.
response
.
data
)
}
},
async
createEffect
({
commit
},
payload
)
{
try
{
const
response
=
await
instance
.
post
(
'/effects/'
,
payload
)
commit
(
'addEffect'
,
response
.
data
)
}
catch
(
err
)
{
commit
(
'addError'
,
err
.
response
.
data
)
}
},
async
updateEffect
({
commit
},
payload
)
{
try
{
await
instance
.
patch
(
payload
.
url
,
payload
)
commit
(
'setEffect'
,
payload
)
}
catch
(
err
)
{
console
.
log
(
err
)
commit
(
'addError'
,
err
.
response
.
data
)
}
},
},
modules
:
{
}
...
...
src/views/Editor.vue
View file @
99176a92
...
...
@@ -37,7 +37,7 @@ export default {
this
.
checkExportProgress
(
this
.
activeExports
[
0
])
}
},
...
mapActions
([
'getProject'
,
'loadExports'
,
'checkExportProgress'
]),
...
mapActions
([
'getProject'
,
'loadExports'
,
'checkExportProgress'
,
'loadEffects'
]),
...
mapMutations
([
'addError'
,
'setProject'
,
'setExports'
])
},
computed
:
{
...
...
@@ -53,7 +53,8 @@ export default {
async
mounted
()
{
try
{
let
project_id
=
this
.
$route
.
params
.
id
await
this
.
loadExports
(
project_id
)
this
.
loadExports
(
project_id
)
this
.
loadEffects
(
project_id
)
let
results
=
await
this
.
getProject
(
project_id
)
this
.
setProject
(
results
.
data
)
this
.
hasData
=
true
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment