EDL to HTML with thumbnails for every shot change

For video production companies video asset management is an important part of our post-production workflow. Being able to re-use footage can reduce our production costs considerably and enhance the creative editing process. The more footage we have, the better the video will look.

As our best footage always ends up one way or another in a sequence, it made sense to us to use Edit Decisions Lists as the starting point of our online video asset management.

The problem is that EDLs are text-based and, therefore, don't give a visual representation of the shots. For this reason, we needed to convert the information in an EDL, the timecodes, into thumbnails that would correspond to every shot change of the original sequence. We also wanted to use these thumbnails to control a low-res video file so we could preview not just a frame but the whole length of a clip.

For this purpose, we designed the following EDL to HTML workflow using Powershell, FFmpeg and the JW Player. We hope you'll find it useful.

Create the EDL using your Non Linear Editor of choice.

  1. Open a copy of your sequence in the timeline.
  2. Make sure that the first frame of action is at the beginning of your sequence (delete any preceding clips such as bars, clocks, etc.).
  3. Change the timecode of your sequence to 00:00:00:00 (instead of 01:00:00:00 or 10:00:00:00).
  4. Export your sequence as a CMX_3600 EDL.

This is how your EDL should look like:

TITLE:   Video Production London Showreel
FCM: NON-DROP FRAME
001     AX    V     C        00:00:10:11 00:00:12:13 00:00:00:00 00:00:42:00
* FROM CLIP NAME:  Third Eye
002     AX    V     C        00:00:14:15 00:00:16:17 00:00:42:00 00:01:36:00
* FROM CLIP NAME:  Tech Watch
003     AX    V     C        00:00:18:19 00:00:20:21 00:01:36:00 00:02:31:00
* FROM CLIP NAME:  World Business
004     AX    V     C        00:00:22:23 00:00:24:00 00:02:31:00 00:03:09:00
* FROM CLIP NAME:  Business of Sport

Create 2 video files.

  1. Delete all the effects and dissolves (http://forums.creativecow.net/thread/45/871585) to have clean shot changes.
  2. In the timeline make sure that the only visible video layer is V1 or delete the rest of the layers.
  3. Export your sequence as a low-res video file for web streaming/downloading.
  4. Delete the first 6 frames of your sequence* and export your sequence as a self-contained movie or as any quick export compatible with FFmpeg.

*FFmpeg has two ways of seeking (-ss) to position (When used as an input option (before -i), seeks in this input file to position. When used as an output option (before an output filename), decodes but discards input until the timestamps reach position. The input option is frame accurate but is slower than the output option. By removing 6 frames at the beginning of our sequence we can use the faster output option and expect to generate the right thumbnail for every clip.

Convert the EDL into a .BAT file to generate the thumbnails using FFMPEG.

Copy and paste the text below into Powershell (don't forget to change the paths in the first 2 lines and the name of the video file in line 7). If you have an NTSC sequence you'll need to replace the frames by multiples of "33" instead of "40".

$sourceEDL = "C:\EDL\" # Change this accordingly
$newBatchFile = "C:\FFmpeg_Thumbnail_Generator.bat" # Change this accordingly
Get-ChildItem $sourceEDL -Recurse | .{process{ if (!$_.PSIsContainer) {
    # read all text once
    $content = [System.IO.File]::ReadAllText($_.FullName) `
    -replace "(?m)^(\*|F|T)(.*)`r`n", "" `
    -replace "(.*)\w\w    \w     \w        \w\w:\w\w:\w\w:\w\w \w\w:\w\w:\w\w:\w\w", "ffmpeg -i videos\your_video_file.mov -f image2 -ss" `
    -replace "(\w)(\w)(:)(\w)(\w)(:)(\w)(\w)(:)(\w)(\w) (\w)(\w)(:)(\w)(\w)(:)(\w)(\w)(:)(\w)(\w)", '$1$2:$4$5:$7$8:$10$11 -f image2 -s 146x82 -vframes 1 images\$1$2$4$5$7$8$10$11.jpg' `
    -replace ":00 ", ".000 " `
    -replace ":01 ", ".040 " `
    -replace ":02 ", ".080 " `
    -replace ":03 ", ".120 " `
    -replace ":04 ", ".160 " `
    -replace ":05 ", ".200 " `
    -replace ":06 ", ".240 " `
    -replace ":07 ", ".280 " `
    -replace ":08 ", ".320 " `
    -replace ":09 ", ".360 " `
    -replace ":10 ", ".400 " `
    -replace ":11 ", ".440 " `
    -replace ":12 ", ".480 " `
    -replace ":13 ", ".520 " `
    -replace ":14 ", ".560 " `
    -replace ":15 ", ".600 " `
    -replace ":16 ", ".640 " `
    -replace ":17 ", ".680 " `
    -replace ":18 ", ".720 " `
    -replace ":19 ", ".760 " `
    -replace ":20 ", ".800 " `
    -replace ":21 ", ".840 " `
    -replace ":22 ", ".880 " `
    -replace ":23 ", ".920 " `
    -replace ":24 ", ".960 " | Set-Content "$newBatchFile" }}}

Create the thumbnails

If it isn't, place the new batch file in the same folder where FFmpeg.exe resides and double click the batch file, which should look similar to this one:

ffmpeg -i videos\your_video_file.mov -f image2 -ss 00:00:00.000 -f image2 -s 146x82 -vframes 1 images\00000000.jpg
ffmpeg -i videos\your_video_file.mov -f image2 -ss 00:00:42.000 -f image2 -s 146x82 -vframes 1 images\00004200.jpg
ffmpeg -i videos\your_video_file.mov -f image2 -ss 00:01:36.000 -f image2 -s 146x82 -vframes 1 images\00013600.jpg
ffmpeg -i videos\your_video_file.mov -f image2 -ss 00:02:31.000 -f image2 -s 146x82 -vframes 1 images\00023100.jpg

Create an HTML file with some JavaScript to link the images to a video player:

Copy and paste the text below into Powershell to convert timecodes into seconds (in order to enable seeking in the video player).

$sourceEDL = "C:\EDL\" # Change this path accordingly
$destination = "C:\convert_timecode_to_seconds.ps1" # Change this path accordingly
$fromClip = "`r`n\* FROM CLIP NAME:  "
$metadata = "(?m)^(T|F)(.*)`r`n"
$clipTimecodes = "(?m)^\d.*AX    V     C        (\d)(\d):(\d)(\d):(\d)(\d):(\d)(\d) (\d)(\d):(\d)(\d):(\d)(\d):(\d)(\d)"
$sequenceTimecodes = "(\d)(\d):(\d)(\d):(\d)(\d):(\d)(\d) (\d)(\d):(\d)(\d):(\d)(\d):(\d)(\d)"
$seconds = "</h5></a>`" -f 1 -replace `"\( `", `"(`" -replace `" \)`", `")`" | add-content chapter_navigation.html `r`n"
Get-ChildItem $sourceEDL -Recurse | .{process{ if (!$_.PSIsContainer) {
    # read all text once
    $content = [System.IO.File]::ReadAllText($_.FullName) `
    -replace "$fromClip", "" `
    -replace "$metadata", "" `
    -replace "$clipTimecodes", '"<a title=`"IN $1$2:$3$4:$5$6.$7$8 - OUT $9$10:$11$12:$13$14.$15$16`" onclick=`"jwplayer().seek(",' `
    -replace "$sequenceTimecodes", '(New-TimeSpan -hours $1$2 -minutes $3$4 -seconds $5$6).TotalSeconds, "); return false`" href=`"#`"><img src=`"images/$1$2$3$4$5$6$7$8.jpg`"><h5>' `
    -replace "`r`n", "$seconds" | Set-Content $destination }}}

Run the new PS1 file “convert_timecode_to_seconds.ps1”, which will generate a html file: "chapter_navigation.html".

"<a title=`"IN 00:00:10.11 - OUT 00:00:12.13`" onclick=`"jwplayer().seek(", (New-TimeSpan -hours 00 -minutes 00 -seconds 00).TotalSeconds, "); return false`" href=`"#`"><img src=`"images/00000000.jpg`"><h5>Third Eye</h5></a>" -f 1 -replace "\( ", "(" -replace " \)", ")" | add-content chapter_navigation.html 
"<a title=`"IN 00:00:14.15 - OUT 00:00:16.17`" onclick=`"jwplayer().seek(", (New-TimeSpan -hours 00 -minutes 00 -seconds 42).TotalSeconds, "); return false`" href=`"#`"><img src=`"images/00004200.jpg`"><h5>Tech Watch</h5></a>" -f 1 -replace "\( ", "(" -replace " \)", ")" | add-content chapter_navigation.html 
"<a title=`"IN 00:00:18.19 - OUT 00:00:20.21`" onclick=`"jwplayer().seek(", (New-TimeSpan -hours 00 -minutes 01 -seconds 36).TotalSeconds, "); return false`" href=`"#`"><img src=`"images/00013600.jpg`"><h5>World Business</h5></a>" -f 1 -replace "\( ", "(" -replace " \)", ")" | add-content chapter_navigation.html 
"<a title=`"IN 00:00:22.23 - OUT 00:00:24.00`" onclick=`"jwplayer().seek(", (New-TimeSpan -hours 00 -minutes 02 -seconds 31).TotalSeconds, "); return false`" href=`"#`"><img src=`"images/00023100.jpg`"><h5>Business of Sport</h5></a>" -f 1 -replace "\( ", "(" -replace " \)", ")" | add-content chapter_navigation.html 

Below you'll find an example of how you can use "chapter_navigation.html" to sync the thumbnails to the JW video player.


<script type="text/javascript" src="jwplayer/jwplayer.js"></script>
<div id="player">
<div id="container">Loading the player ...</div>
<script type="text/javascript"> jwplayer("container").setup({
        "flashplayer": "jwplayer/player.swf",
        "file": "videos/videofile.mp4",
        "height": "308",
        "width": "512",
        "autostart": "false",
        "controlbar.position": "bottom",
        });
</script>
</div>
<a title="IN 00:00:10.11 - OUT 00:00:12.13" onclick="jwplayer().seek(0); return false" href="#"><img src="images/00000000.jpg"><h5>Third Eye</h5></a>
<a title="IN 00:00:14.15 - OUT 00:00:16.17" onclick="jwplayer().seek(42); return false" href="#"><img src="images/00004200.jpg"><h5>Tech Watch</h5></a>
<a title="IN 00:00:18.19 - OUT 00:00:20.21" onclick="jwplayer().seek(96); return false" href="#"><img src="images/00013600.jpg"><h5>World Business</h5></a>
<a title="IN 00:00:22.23 - OUT 00:00:24.00" onclick="jwplayer().seek(151); return false" href="#"><img src="images/00023100.jpg"><h5>Business of Sport</h5></a>

Demo

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
We are sorry, but we can only accept messages from human beings.
Image CAPTCHA
Enter the characters shown in the image.

Video Production London Blog

  • I still remember my first film as if it were yesterday; I was 13 years old and my father had just bought our first video camera for the summer holidays. I had never hold a camera before in my life...

  • My two great obsessions in life are bicycles and making videos. And books. Okay, my three great obsessions in life are bicycles, making videos and books. So when I got the opportunity to...

glqxz9283 sfy39587p08