Embed Comskip's EDL Markers In H.264 Mpeg4 Video for iPad?

Here you can ask your questions on how to use Comskip for the detection of commercials. Also questions on how to remove commercials are welcome
Post Reply
stvs
Posts: 5
Joined: Sat Oct 06, 2012 11:27 am

Embed Comskip's EDL Markers In H.264 Mpeg4 Video for iPad?

Post by stvs »

I love Comskip -- it's probably the executable my computer devotes most of its cycles to.

I transfer a lot of tv content as h.264 mpeg4 files to mobile devices, iPads and the like, and would like to make Comskip mobile as well. Currently, Comskip's .edl files reside on my tv server and work great at home, but mobile device video players don't speak edl, and there's no way I know of to make direct use of edl's on an iPad.

But I have seen chapter information added to h.264 video that the iPad knows how to navigate. Hence the idea: use Comskip's .edl file to add chapter headings to h.264 files at the end of each commercial. When a commercial appears, just skip to the next chapter.

Does anyone know of a basic command that adds chapter headings to h.264 video files?

With this command in hand, it becomes trivial to write a script that adds Comskip information to every video and take Comskip on the road with iPads or other mobile devices. I'd prefer a unix command that will go with an OS X + EyeTV + Turbo.264 DVR setup, but if people are aware of a windows utility, that will help with the googling for a bsd solution.
stvs
Posts: 5
Joined: Sat Oct 06, 2012 11:27 am

Re: Embed Comskip's EDL Markers In H.264 Mpeg4 Video for iPa

Post by stvs »

I just googled the answer using keywords from this post. There are two possibilities: mp4chaps from the mp4v2 project, and SublerCLI from a googlecode project. I'll test this out and report back.

mp4chaps comes from, e.g. "sudo port install mp4v2" using macports.
stvs
Posts: 5
Joined: Sat Oct 06, 2012 11:27 am

Re: Embed Comskip's EDL Markers In H.264 Mpeg4 Video for iPa

Post by stvs »

I've modified ETVComskip to add Comskip information to EyeTV exports for iPad/iPhone/Apple TV files. ETVComskip works great for EyeTV's original recordings, but the Comskip information isn't included with exports to iPad/iPhone/Apple TV files created by EyeTV or Turbo.264. Result: iTunes exports and wifi streams have ads. This modification addresses this issue by adding Comskip .edl information as chapters within the H.264 .m4v files exported by EyeTV and Turbo.264, providing a mobile Comskip solution: when the ads appear, skip to the next chapter. This is a lot easier and faster than using the (barely functional) time swiping capability to guess where the show starts. It also avoids the problem of false detections by not deleting any program material.

See this google code page for details: http://code.google.com/p/etv-comskip/is ... tail?id=54

See this google code page for details about how to modify ETVComskip for HD: http://code.google.com/p/etv-comskip/is ... tail?id=53

Here's a Python (and original perl) code that converts .edl files to chapter files for mp4chaps:

mp4chapsm4v.py

Code: Select all

#!/usr/bin/env python
# Apply mp4chaps to every file in a directory if there exists a non-zero length file whatever.edl in that directory

import os
from os import listdir
from os.path import isfile, join
import sys
# Avoid using libraries because old ETVComskip MarkCommercials.app doesn't have 'em

mp4chaps = '/opt/local/bin/mp4chaps'

def sec2hhmmss(secs):
    """Convert seconds to string HH:MM:SS.SSS format."""
    rem = secs/3600
    hh = int(rem)
    rem = (rem-hh)*60
    mm = int(rem)
    rem = (rem-mm)*60
    ss = int(rem)
    rem = (rem-ss)
    rem = '%.3f' % rem  # millisecond precision
    rem = rem.replace('0.','.')
    return '%02d:%02d:%02d%s' % (hh,mm,ss,rem)

def split_whitespace_nolibs(str):
    """Split a string by whitespace without using re or shlex libraries.."""
    strs = filter(None,str.split('\t'))
    strs = map(lambda s: s.split(' '),strs)
    strs = filter(None,[item for sublist in strs for item in sublist])
    return strs

def edl2mp4chaps(edl_file,file):
    """Convert an edl file into an mp4chaps file."""
    txt_file = file.replace('.m4v','.chapters.txt')
    ftxt = open(txt_file,'w')

    comskipno = 0
    comskipchapno = 0
    lines = [line.strip() for line in open(edl_file)]
    for line in lines:
        times = map(float,split_whitespace_nolibs(line))
        if (comskipno == 0 and times[0] != 0.0):
            comskipno += 1
        if (len(times) < 2 or times[2] == 0.0):
            if (times[0] != 0.0):
                ftxt.write('%s Chapter %d End\n' % (sec2hhmmss(times[0]),comskipno))
            else:
                ftxt.write('00:00:00.000 Beginning\n')
            comskipno += 1
            ftxt.write('%s Chapter %d Start\n' % (sec2hhmmss(times[1]),comskipno))
        else:
            # never seen this case, but here for logical consistency
            comskipchapno += 1
            if (times[0] != 0.0):
                ftxt.write('%s Chapter %d Start\n' % (sec2hhmmss(times[0]),comskipchapno))
            else:
                ftxt.write('00:00:00.000 Beginning\n')
            ftxt.write('%s Chapter %d End\n' % (sec2hhmmss(times[1]),comskipchapno))
    ftxt.close()
    return

def mp4chaps_all_m4v(dir):
    """Apply an edl file's entries to all m4v files in a directory."""
    os.chdir(dir)
    edl_file = ""
    files = [ file for file in listdir(dir) if isfile(join(dir,file)) ]
    for file in files:
        if file.find('.edl') != -1:
            edl_file = file
            break
    if edl_file != "" and os.path.getsize(edl_file) != 0 and os.path.isfile(mp4chaps):
        for file in files:
            if file.find('.m4v') != -1:
                # remove all chapters
                cmd = mp4chaps + ' -r ' + file + ' > /dev/null 2>&1'
                rc = os.system(cmd)
                # create chapter file
                edl2mp4chaps(edl_file,file)
                # import chapters
                cmd = mp4chaps + ' -i ' + file + ' > /dev/null 2>&1'
                rc = os.system(cmd)
    return
            
# mp4chaps_all_m4v("/Users/username/Desktop")

mp4chaps_all_m4v(str(sys.argv[1]))


### Original perl code for edl2mp4chaps
### #!/usr/bin/perl
### 
### ########################################
### # CONVERT EDL FILES TO MP4CHAPS FILES  #
### ########################################
### 
### use strict;
### 
### my $edl_file = $ARGV[0] || './test.edl' ;
### 
### ##########
### #  HELP  #
### ##########
### 
### if ( $ARGV[0] =~ /^-+h/i || $#ARGV < 0 ) {
###     print qq`
### _________________________________________________________
### 
### This tool will convert the EDL file (from Comskip)
### to a m4vchaps chapter file for H.264 video.
### 
###   USE: perl $0 ./test.edl
### 
### Enjoy! :-P
### _________________________________________________________
### `;
###     exit ;
### }
### 
### die("Please specify an EDL file.") if ($edl_file !~ /\.edl$/);
### my $txt_file = $edl_file;
### $txt_file =~ s/\.edl$/.chapters.txt/;
### 
### sub sec2hhmmss {
###     my $rem = $_[0]/3600;
###     my $hh = int($rem);
###     $rem = ($rem - $hh)*60;
###     my $mm = int($rem);
###     $rem = ($rem - $mm)*60;
###     my $ss = int($rem);
###     $rem = ($rem - $ss);
###     $rem = sprintf("%.3f",$rem);  # millisecond precision
###     $rem =~ s/^0//;
###     return sprintf("%02d:%02d:%02d%s",$hh,$mm,$ss,$rem);
### }
### 
### open (EDL,$edl_file) || die("Cannot open edl file " . $edl_file);
### open (TXT,">",$txt_file) || die("Cannot open txt file " . $txt_file);
### my $line;
### my @times;
### my $comskipno = 0;
### my $comskipchapno = 0;
### while ($line = <EDL>) {
###     chomp $line;
###     # parse the space-delimited edl ascii times into an array of numbers
###     @times = split ' ', $line;
###     @times = map {$_+0} @times; # (unnecessarily) convert strings to numbers
###     print TXT "00:00:00.000 Beginning\n" if ($comskipno == 0 and $times[0] != 0);
###     if ($#times < 2 || $times[2] == 0) {
###         $comskipno++;
###         print TXT sprintf("%s Commercial %d Start\n",sec2hhmmss($times[0]),$comskipno);
###         print TXT sprintf("%s Commercial %d End\n",sec2hhmmss($times[1]),$comskipno);
###     } else {
###         # never seen this case, but here for logical consistency
###         $comskipchapno++;
###         print TXT sprintf("%s Chapter %d Start\n",sec2hhmmss($times[0]),$comskipchapno);
###         print TXT sprintf("%s Chapter %d End\n",sec2hhmmss($times[1]),$comskipchapno);
###     }
### }
### close (EDL) ;
### close (TXT) ;
[/size]
kiwijunglist
Posts: 19
Joined: Mon Oct 22, 2012 10:23 am

Re: Embed Comskip's EDL Markers In H.264 Mpeg4 Video for iPa

Post by kiwijunglist »

Any chance you can compile this for users who don't have python installed? (me :) )
kiwijunglist
Posts: 19
Joined: Mon Oct 22, 2012 10:23 am

Re: Embed Comskip's EDL Markers In H.264 Mpeg4 Video for iPa

Post by kiwijunglist »

I installed python but I get this error when i run your script

D:\TV RECORDINGS\TV3\3 News>convert.py
Traceback (most recent call last):
File "D:\TV RECORDINGS\TV3\3 News\convert.py", line 86, in <module>
mp4chaps_all_m4v(str(sys.argv[1]))
IndexError: list index out of range
Post Reply