<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def preprocess(self, data):
 """ Processes popcorn JSON and builds a sane data model out of it @param data : The popcorn editor project json blob """


        print 'Beginning pre-process...'
        for url, video in data['media'][0]['clipData'].iteritems():
            print 'Downloading {0} from {1}.'.format(video['title'], url)

            # Removes all white spaces and non alphanumeric chars from title
            video['title'] = re.sub(
                '[^\w\.]',
                '',
                video['title']
            ) + '.webm'

            urllib.urlretrieve(url, video['title'])
            self.base_videos.append(video['title'])
            print 'video downloaded as %s!' % video['title']
        print 'All videos downloaded.'

        events = [event for track in data['media'][0]['tracks']
                  for event in track['trackEvents']]

        for event in events:
            if event['type'] == 'skip' or event['type'] == 'loopPlugin':
                edit = TrackEdit(event['type'], event['popcornOptions'])

                self.track_edits.append(edit)

            if event['type'] == 'text' or event['type'] == 'image':
                item = TrackItem(event['type'], event['popcornOptions'])

                item.options['start_stamp'] = \
                    item.options['start']
                item.options['end_stamp'] = \
                    item.options['end']
                item.options['x_px'] = percent_to_px(
                    item.options['left'],
                    self.size[0]
                )
                item.options['y_px'] = percent_to_px(
                    item.options['top'],
                    self.size[1]
                )

                self.track_items.append(item)

            if event['type'] == 'sequencer':
                video = TrackVideo(
                    event['type'],
                    event['popcornOptions']['source'][0],
                    event['popcornOptions']
                )
                self.track_videos.append(video)

        self.parse_duration()

        cfilter = r'color=c={0}:s={1}x{2}:d={3};aevalsrc=0:d={4}'.format(
            self.background_color,
            self.size[0],
            self.size[1],
            self.duration,
            self.duration,
        )
        call(['ffmpeg', '-filter_complex', cfilter, '-y',
              self.current_video.name])