1ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi/*
2ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Copyright (C) 2010 The Android Open Source Project
3ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi *
4ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Licensed under the Apache License, Version 2.0 (the "License");
5ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * you may not use this file except in compliance with the License.
6ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * You may obtain a copy of the License at
7ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi *
8ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi *      http://www.apache.org/licenses/LICENSE-2.0
9ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi *
10ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Unless required by applicable law or agreed to in writing, software
11ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * distributed under the License is distributed on an "AS IS" BASIS,
12ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * See the License for the specific language governing permissions and
14ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * limitations under the License.
15ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */
16ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1781393d6dc5767f7784a00958095614a37bf1a91aGil Dobjanschipackage com.android.videoeditor.service;
18ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
19ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.io.File;
20ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.io.FileInputStream;
21ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.io.FileNotFoundException;
22ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.io.FileOutputStream;
23ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.io.IOException;
24ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.io.StringWriter;
25ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.util.ArrayList;
26ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.util.List;
27ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
28ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport org.xmlpull.v1.XmlPullParser;
29ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport org.xmlpull.v1.XmlPullParserException;
30ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport org.xmlpull.v1.XmlSerializer;
31ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
32ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.media.videoeditor.MediaProperties;
33ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.media.videoeditor.MediaVideoItem;
34ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.media.videoeditor.VideoEditor;
35ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.media.videoeditor.VideoEditor.PreviewProgressListener;
36ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.net.Uri;
37ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.util.Xml;
38ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.view.SurfaceHolder;
39ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
40ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
41ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi/**
42045133a84c417b1469050980990f1623c6448e2cShih-chia Cheng * The video editor project encapsulates the video editor and the project metadata.
43ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */
44ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschipublic class VideoEditorProject {
45ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    // The name of the metadata file
46ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private final static String PROJECT_METADATA_FILENAME = "metadata.xml";
47ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
48ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public static final int DEFAULT_ZOOM_LEVEL = 20;
49ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
50ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    // XML definitions
51ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static final String TAG_PROJECT = "project";
52ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static final String TAG_MOVIE = "movie";
53f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    private static final String TAG_DOWNLOAD = "download";
54ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static final String ATTR_NAME = "name";
55ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static final String ATTR_URI = "uri";
56ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static final String ATTR_SAVED = "saved";
57ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static final String ATTR_THEME = "theme";
58ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static final String ATTR_PLAYHEAD_POSITION = "playhead";
59ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static final String ATTR_DURATION = "duration";
60ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static final String ATTR_ZOOM_LEVEL = "zoom_level";
61f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    private static final String ATTR_MIME = "mime";
62f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    private static final String ATTR_FILENAME = "filename";
63f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    private static final String ATTR_TIME = "time";
64ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
65ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    // Instance variables
66ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private final VideoEditor mVideoEditor;
67ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private final String mProjectPath;
68ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private final long mProjectDurationMs;
69f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    private final List<Download> mDownloads;
70ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private String mProjectName;
71ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private long mLastSaved;
72ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private Uri mExportedMovieUri;
73ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private int mAspectRatio;
74ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private String mTheme;
75ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private long mPlayheadPosMs;
76ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private int mZoomLevel;
77ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private List<MovieMediaItem> mMediaItems = new ArrayList<MovieMediaItem>();
78ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private List<MovieAudioTrack> mAudioTracks = new ArrayList<MovieAudioTrack>();
7905665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi    private boolean mClean;
80ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
81ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
82f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     * Download item
83f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     */
84f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    public static class Download {
85f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        private final String mMediaUri;
86f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        private final String mMimeType;
87f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        private final String mFilename;
88f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        private final long mTime;
89f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
90f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        /**
91f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         * Constructor
92f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         *
93f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         * @param mediaUri The media URI
94f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         * @param mimeType The mime type
95f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         * @param filename The filename
96f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         * @param time The time when the file was downloaded
97f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         */
98f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        private Download(String mediaUri, String mimeType, String filename, long time) {
99f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            mMediaUri = mediaUri;
100f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            mMimeType = mimeType;
101f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            mFilename = filename;
102f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            mTime = time;
103f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        }
104f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
105f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        /**
106f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         * @return the media URI
107f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         */
108f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        public String getMediaUri() {
109f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            return mMediaUri;
110f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        }
111f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
112f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        /**
113f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         * @return the mime type
114f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         */
115f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        public String getMimeType() {
116f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            return mMimeType;
117f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        }
118f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
119f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        /**
120f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         * @return the filename
121f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         */
122f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        public String getFilename() {
123f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            return mFilename;
124f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        }
125f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
126f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        /**
127f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         * @return the mTime
128f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi         */
129f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        public long getTime() {
130f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            return mTime;
131f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        }
132f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    }
133f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
134f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    /**
135ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Constructor
136ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
137ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param videoEditor The video editor. Note that this can be null when
138ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *  we create the project for the purpose of displaying a project preview.
139ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param projectPath The project path
140ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param projectName The project name
141ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param lastSaved Time when project was last saved
142ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param playheadPosMs The playhead position
143ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param durationMs The project duration
144ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param zoomLevel The zoom level
145ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param exportedMovieUri The exported movie URI
146ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param theme The project theme
147f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     * @param downloads The list of downloads
148ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
149ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    VideoEditorProject(VideoEditor videoEditor, String projectPath, String projectName,
150ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            long lastSaved, long playheadPosMs, long durationMs, int zoomLevel,
151f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            Uri exportedMovieUri, String theme, List<Download> downloads) {
152ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mVideoEditor = videoEditor;
153ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (videoEditor != null) {
154ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            mAspectRatio = videoEditor.getAspectRatio();
155ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
156ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
157f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        if (downloads != null) {
158f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            mDownloads = downloads;
159f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        } else {
160f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            mDownloads = new ArrayList<Download>();
161f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        }
162ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mProjectPath = projectPath;
163ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mProjectName = projectName;
164ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mLastSaved = lastSaved;
165ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mPlayheadPosMs = playheadPosMs;
166ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mProjectDurationMs = durationMs;
167ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mZoomLevel = zoomLevel;
168ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mExportedMovieUri = exportedMovieUri;
169ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mTheme = theme;
17005665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = true;
17105665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi    }
17205665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi
17305665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi    /**
17405665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi     * @param clean true if this is clean
17505665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi     */
17605665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi    public void setClean(boolean clean) {
17705665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = clean;
17805665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi    }
17905665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi
18005665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi    /**
18105665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi     * @return true if no change was made
18205665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi     */
18305665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi    public boolean isClean() {
18405665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        return mClean;
185ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
186ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
187ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
188ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The project path
189ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
190ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public String getPath() {
191ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mProjectPath;
192ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
193ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
194ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
195ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param projectName The project name
196ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
197ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public void setProjectName(String projectName) {
198ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mProjectName = projectName;
19905665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
200ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
201ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
202ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
203ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The project name
204ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
205ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public String getName() {
206ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mProjectName;
207ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
208ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
209ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
210ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return Time when time was last saved
211ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
212ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public long getLastSaved() {
213ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mLastSaved;
214ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
215ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
216ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
217ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The project duration.
218ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
219ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Note: This method should only be called to retrieve the project duration
220ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * as saved on disk. Once a project is opened call computeDuration() to get
221ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * the current duration.
222ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
223ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public long getProjectDuration() {
224ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mProjectDurationMs;
225ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
226ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
227ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
228ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The zoom level
229ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
230ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public int getZoomLevel() {
231ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mZoomLevel;
232ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
233ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
234ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
235ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param zoomLevel The zoom level
236ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
237ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public void setZoomLevel(int zoomLevel) {
238ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mZoomLevel = zoomLevel;
239ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
240ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
241ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
242ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The aspect ratio
243ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
244ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public int getAspectRatio() {
245ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mAspectRatio;
246ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
247ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
248ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
249ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The playhead position
250ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
251ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public long getPlayheadPos() {
252ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mPlayheadPosMs;
253ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
254ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
255ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
256ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param playheadPosMs The playhead position
257ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
258ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public void setPlayheadPos(long playheadPosMs) {
259ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mPlayheadPosMs = playheadPosMs;
260ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
261ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
262ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
263ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param aspectRatio The aspect ratio
264ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
265ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void setAspectRatio(int aspectRatio) {
266ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mAspectRatio = aspectRatio;
26705665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
268ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
269ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
270ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
271ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Add the URI of an exported movie
272ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
273ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param uri The movie URI
274ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
275ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void addExportedMovieUri(Uri uri) {
276ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mExportedMovieUri = uri;
27705665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
278ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
279ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
280ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
281ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The exported movie URI
282ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
283ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public Uri getExportedMovieUri() {
284ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mExportedMovieUri;
285ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
286ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
287ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
288ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param theme The theme
289ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
290ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void setTheme(String theme) {
291ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mTheme = theme;
29205665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
293ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
294ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
295ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
296ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The theme
297ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
298ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public String getTheme() {
299ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mTheme;
300ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
301ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
302ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
303ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Set the media items
304ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
305ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItems The media items
306ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
307ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void setMediaItems(List<MovieMediaItem> mediaItems) {
308ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mMediaItems = mediaItems;
30905665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
310ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
311ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
312ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
313ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Insert a media item after the specified media item id
314ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
315ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItem The media item
316ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param afterMediaItemId Insert after this media item id
317ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
318ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void insertMediaItem(MovieMediaItem mediaItem, String afterMediaItemId) {
319ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (afterMediaItemId == null) {
320ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mMediaItems.size() > 0) {
321ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                // Invalidate the transition at the beginning of the timeline
322ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                final MovieMediaItem firstMediaItem = mMediaItems.get(0);
323ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (firstMediaItem.getBeginTransition() != null) {
324ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    firstMediaItem.setBeginTransition(null);
325ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
326ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
327ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
328ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            mMediaItems.add(0, mediaItem);
32905665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi            mClean = false;
330ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
331ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final int mediaItemCount = mMediaItems.size();
332ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            for (int i = 0; i < mediaItemCount; i++) {
333ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                final MovieMediaItem mi = mMediaItems.get(i);
334ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (mi.getId().equals(afterMediaItemId)) {
335ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    // Invalidate the transition at the end of this media item
336ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    mi.setEndTransition(null);
337ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    // Invalidate the reference in the next media item (if any)
338ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    if (i < mediaItemCount - 1) {
339ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        mMediaItems.get(i + 1).setBeginTransition(null);
340ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    }
341ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
342ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    // Insert the new media item
343ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    mMediaItems.add(i + 1, mediaItem);
34405665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi                    mClean = false;
345ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    return;
346ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
347ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
348ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
349ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            throw new IllegalArgumentException("MediaItem not found: " + afterMediaItemId);
350ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
351ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
352ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
353ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
354ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Update the specified media item
355ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
356ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param newMediaItem The media item can be a new instance of the media
357ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *      item or an updated version of the same instance.
358ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
359ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void updateMediaItem(MovieMediaItem newMediaItem) {
360ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final String newMediaItemId = newMediaItem.getId();
361ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int count = mMediaItems.size();
362ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < count; i++) {
363ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem mediaItem = mMediaItems.get(i);
364ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mediaItem.getId().equals(newMediaItemId)) {
365ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                mMediaItems.set(i, newMediaItem);
36605665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi                mClean = false;
367ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                // Update the transitions of the previous and next item
368ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (i > 0) {
369ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    final MovieMediaItem prevMediaItem = mMediaItems.get(i - 1);
370ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    prevMediaItem.setEndTransition(newMediaItem.getBeginTransition());
371ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
372ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
373ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (i < count - 1) {
374ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    final MovieMediaItem nextMediaItem = mMediaItems.get(i + 1);
375ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    nextMediaItem.setBeginTransition(newMediaItem.getEndTransition());
376ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
377ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                break;
378ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
379ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
380ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
381ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
382ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
383ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Remove the specified media item
384ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
385ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
386ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param transition The transition to be set between at the delete
387ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *      position
388ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
389ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void removeMediaItem(String mediaItemId, MovieTransition transition) {
390ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        String prevMediaItemId = null;
391ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int count = mMediaItems.size();
392ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < count; i++) {
393ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem mediaItem = mMediaItems.get(i);
394ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mediaItem.getId().equals(mediaItemId)) {
395ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                mMediaItems.remove(i);
39605665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi                mClean = false;
397ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (transition != null) {
398ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    addTransition(transition, prevMediaItemId);
399ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                } else {
400ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    if (i > 0) {
401ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        final MovieMediaItem prevMediaItem = mMediaItems.get(i - 1);
402ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        prevMediaItem.setEndTransition(null);
403ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    }
404ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
405ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    if (i < count - 1) {
406ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        final MovieMediaItem nextMediaItem = mMediaItems.get(i);
407ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        nextMediaItem.setBeginTransition(null);
408ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    }
409ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
410ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                break;
411ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
412ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
413ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            prevMediaItemId = mediaItem.getId();
414ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
415ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
416ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
417ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
418ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The media items list
419ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
420ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public List<MovieMediaItem> getMediaItems() {
421ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mMediaItems;
422ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
423ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
424ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
425ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The media item count
426ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
427ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public int getMediaItemCount() {
428ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mMediaItems.size();
429ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
430ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
431ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
432ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
433ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
434ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The media item
435ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
436ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieMediaItem getMediaItem(String mediaItemId) {
437ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (MovieMediaItem mediaItem : mMediaItems) {
438ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mediaItem.getId().equals(mediaItemId)) {
439ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                return mediaItem;
440ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
441ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
442ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
443ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return null;
444ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
445ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
446ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
447ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The first media item
448ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
449ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieMediaItem getFirstMediaItem() {
450ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mMediaItems.size() == 0) {
451ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return null;
452ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
453ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return mMediaItems.get(0);
454ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
455ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
456ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
457ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
458ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Check if the specified media item id is the first media item
459ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
460ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
461ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
462ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return true if this is the first media item
463ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
464ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public boolean isFirstMediaItem(String mediaItemId) {
465ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieMediaItem mediaItem = getFirstMediaItem();
466ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mediaItem == null) {
467ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return false;
468ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
469ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return mediaItem.getId().equals(mediaItemId);
470ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
471ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
472ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
473ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
474fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng     * @return The last media item. {@code null} if no item is in the project.
475ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
476ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieMediaItem getLastMediaItem() {
477ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int count = mMediaItems.size();
478ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (count == 0) {
479ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return null;
480ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
481ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return mMediaItems.get(count - 1);
482ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
483ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
484ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
485ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
486fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng     * Gets the id of the last media item in this project.
487fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng     *
488fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng     * @return Id of the last media item. {@code null} if no item is in this project.
489fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng     */
490fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng    public String getLastMediaItemId() {
491fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng        MovieMediaItem lastMediaItem = getLastMediaItem();
492fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng        if (lastMediaItem != null)
493fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng            return lastMediaItem.getId();
494fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng        return null;
495fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng    }
496fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng
497fa22fa9f65d47c164325477d27570e28c8bfb3aaShih-chia Cheng    /**
498ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Check if the specified media item id is the last media item
499ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
500ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
501ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
502ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return true if this is the last media item
503ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
504ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public boolean isLastMediaItem(String mediaItemId) {
505ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieMediaItem mediaItem = getLastMediaItem();
506ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mediaItem == null) {
507ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return false;
508ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
509ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return mediaItem.getId().equals(mediaItemId);
510ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
511ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
512ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
513ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
514ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Find the previous media item with the specified id
515ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
516ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
517ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The previous media item
518ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
519ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieMediaItem getPreviousMediaItem(String mediaItemId) {
520ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        MovieMediaItem prevMediaItem = null;
521ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (MovieMediaItem mediaItem : mMediaItems) {
522ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mediaItemId.equals(mediaItem.getId())) {
523ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                break;
524ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            } else {
525ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                prevMediaItem = mediaItem;
526ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
527ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
528ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
529ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return prevMediaItem;
530ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
531ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
532ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
533ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Find the next media item with the specified id
534ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
535ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
536ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The next media item
537ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
538ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieMediaItem getNextMediaItem(String mediaItemId) {
539ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        boolean getNext = false;
540ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int count = mMediaItems.size();
541ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < count; i++) {
542ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem mi = mMediaItems.get(i);
543ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (getNext) {
544ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                return mi;
545ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            } else {
546ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (mediaItemId.equals(mi.getId())) {
547ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    getNext = true;
548ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
549ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
550ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
551ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
552ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return null;
553ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
554ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
555ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
556ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Get the previous media item
557ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
558ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param positionMs The current position in ms
559ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The previous media item
560ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
561ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieMediaItem getPreviousMediaItem(long positionMs) {
562ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        long startTimeMs = 0;
563ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        MovieMediaItem prevMediaItem = null;
564ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (MovieMediaItem mediaItem : mMediaItems) {
565ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (positionMs == startTimeMs) {
566ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                break;
567ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            } else if (positionMs > startTimeMs
568ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    && positionMs < startTimeMs + mediaItem.getAppTimelineDuration()) {
569ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                return mediaItem;
570ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            } else {
571ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                prevMediaItem = mediaItem;
572ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
573ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
574ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            startTimeMs += mediaItem.getAppTimelineDuration();
575ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mediaItem.getEndTransition() != null) {
576ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                startTimeMs -= mediaItem.getEndTransition().getAppDuration();
577ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
578ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
579ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
580ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return prevMediaItem;
581ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
582ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
583ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
584ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Get the next media item
585ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
586ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param positionMs The current position in ms
587ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The next media item
588ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
589ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieMediaItem getNextMediaItem(long positionMs) {
590ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        long startTimeMs = 0;
591ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int count = mMediaItems.size();
592ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < count; i++) {
593ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem mediaItem = mMediaItems.get(i);
594ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (positionMs >= startTimeMs
595ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    && positionMs < startTimeMs + mediaItem.getAppTimelineDuration() -
596ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    getEndTransitionDuration(mediaItem)) {
597ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (i < count - 1) {
598ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    return mMediaItems.get(i + 1);
599ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                } else {
600ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    return null;
601ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
602ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            } else if (positionMs >= startTimeMs
603ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    && positionMs < startTimeMs + mediaItem.getAppTimelineDuration()) {
604ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (i < count - 2) {
605ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    return mMediaItems.get(i + 2);
606ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                } else {
607ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    return null;
608ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
609ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            } else {
610ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                startTimeMs += mediaItem.getAppTimelineDuration();
611ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                startTimeMs -= getEndTransitionDuration(mediaItem);
612ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
613ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
614ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
615ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return null;
616ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
617ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
618ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
619ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Get the beginning media item of the specified transition
620ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
621ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param transition The transition
622ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
623ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The media item
624ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
625ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieMediaItem getPreviousMediaItem(MovieTransition transition) {
626ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int count = mMediaItems.size();
627ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < count; i++) {
628ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem mediaItem = mMediaItems.get(i);
629ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (i == 0) {
630ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (mediaItem.getBeginTransition() == transition) {
631ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    return null;
632ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
633ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
634ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
635ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mediaItem.getEndTransition() == transition) {
636ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                return mediaItem;
637ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
638ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
639ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
640ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return null;
641ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
642ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
643ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
644ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Return the end transition duration
645ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
646ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItem The media item
647ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return the end transition duration
648ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
649ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    private static long getEndTransitionDuration(MovieMediaItem mediaItem) {
650ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mediaItem.getEndTransition() != null) {
651ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return mediaItem.getEndTransition().getAppDuration();
652ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
653ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return 0;
654ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
655ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
656ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
657ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
658ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Determine the media item after which a new media item will be inserted.
659ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
660ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param timeMs The inquiry position
661ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
662ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The media item after which the insertion will be performed
663ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
664ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieMediaItem getInsertAfterMediaItem(long timeMs) {
665ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        long beginMs = 0;
666ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        long endMs = 0;
667ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        MovieMediaItem prevMediaItem = null;
668ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int mediaItemsCount = mMediaItems.size();
669ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < mediaItemsCount; i++) {
670ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem mediaItem = mMediaItems.get(i);
671ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
672ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            endMs = beginMs + mediaItem.getAppTimelineDuration();
673ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
674ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mediaItem.getEndTransition() != null) {
675ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (i < mediaItemsCount - 1) {
676ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    endMs -= mediaItem.getEndTransition().getAppDuration();
677ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
678ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
679ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
680ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (timeMs >= beginMs && timeMs <= endMs) {
681ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (timeMs - beginMs < endMs - timeMs) { // Closer to the beginning
682ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    return prevMediaItem;
683ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                } else { // Closer to the end
684ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    return mediaItem; // Insert after this item
685ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
686ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
687ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
688ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            beginMs = endMs;
689ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            prevMediaItem = mediaItem;
690ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
691ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
692ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return null;
693ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
694ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
695ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
696ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return true if media items have different aspect ratios
697ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
698ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public boolean hasMultipleAspectRatios() {
699ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        int aspectRatio = MediaProperties.ASPECT_RATIO_UNDEFINED;
700ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (MovieMediaItem mediaItem : mMediaItems) {
701ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (aspectRatio == MediaProperties.ASPECT_RATIO_UNDEFINED) {
702ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                aspectRatio = mediaItem.getAspectRatio();
703ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            } else if (mediaItem.getAspectRatio() != aspectRatio) {
704ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                return true;
705ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
706ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
707ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
708ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return false;
709ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
710ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
711ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
712ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The list of unique aspect ratios
713ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
714ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public ArrayList<Integer> getUniqueAspectRatiosList() {
715ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final ArrayList<Integer> aspectRatiosList = new ArrayList<Integer>();
716ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (MovieMediaItem mediaItem : mMediaItems) {
717ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            int aspectRatio = mediaItem.getAspectRatio();
718ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (!aspectRatiosList.contains(aspectRatio)) {
719ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                aspectRatiosList.add(aspectRatio);
720ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
721ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
722ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
723ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return aspectRatiosList;
724ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
725ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
726ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
727ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Add a new transition
728ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
729ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param transition The transition
730ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param afterMediaItemId Add the transition after this media item
731ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
732ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void addTransition(MovieTransition transition, String afterMediaItemId) {
733ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int count = mMediaItems.size();
734ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (afterMediaItemId != null) {
735ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            MovieMediaItem afterMediaItem = null;
736ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            int afterMediaItemIndex = -1;
737ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            for (int i = 0; i < count; i++) {
738ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                final MovieMediaItem mediaItem = mMediaItems.get(i);
739ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (mediaItem.getId().equals(afterMediaItemId)) {
740ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    afterMediaItem = mediaItem;
741ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    afterMediaItemIndex = i;
742ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    break;
743ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
744ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
745ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
746ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            // Link the transition to the next and previous media items
747ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (afterMediaItem == null) {
748ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                throw new IllegalArgumentException("Media item not found: " + afterMediaItemId);
749ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
750ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
751ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            afterMediaItem.setEndTransition(transition);
752ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
753ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (afterMediaItemIndex < count - 1) {
754ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                final MovieMediaItem beforeMediaItem = mMediaItems.get(afterMediaItemIndex + 1);
755ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                beforeMediaItem.setBeginTransition(transition);
756ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
757ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
758ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (count == 0) {
759ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                throw new IllegalArgumentException("Media item not found at the beginning");
760ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
761ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
762ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem beforeMediaItem = mMediaItems.get(0);
763ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            beforeMediaItem.setBeginTransition(transition);
764ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
76505665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi
76605665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
767ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
768ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
769ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
770ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Remove the specified transition
771ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
772ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param transitionId The transition id
773ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
774ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void removeTransition(String transitionId) {
775ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int count = mMediaItems.size();
776ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < count; i++) {
777ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem mediaItem = mMediaItems.get(i);
778ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieTransition beginTransition = mediaItem.getBeginTransition();
779ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (beginTransition != null && beginTransition.getId().equals(transitionId)) {
780ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                mediaItem.setBeginTransition(null);
781ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                break;
782ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
783ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
784ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieTransition endTransition = mediaItem.getEndTransition();
785ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (endTransition != null && endTransition.getId().equals(transitionId)) {
786ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                mediaItem.setEndTransition(null);
787ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
788ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
78905665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi
79005665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
791ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
792ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
793ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
794ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Find the transition with the specified id
795ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
796ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param transitionId The transition id
797ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The transition
798ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
799ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieTransition getTransition(String transitionId) {
800ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieMediaItem firstMediaItem = getFirstMediaItem();
801ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (firstMediaItem == null) {
802ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return null;
803ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
804ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
805ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieTransition beginTransition = firstMediaItem.getBeginTransition();
806ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (beginTransition != null && beginTransition.getId().equals(transitionId)) {
807ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return beginTransition;
808ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
809ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
810ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (MovieMediaItem mediaItem : mMediaItems) {
811ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieTransition endTransition = mediaItem.getEndTransition();
812ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (endTransition != null && endTransition.getId().equals(transitionId)) {
813ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                return endTransition;
814ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
815ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
816ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
817ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return null;
818ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
819ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
820ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
821ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Add the overlay
822ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
823ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
824ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param overlay The overlay
825ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
826ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void addOverlay(String mediaItemId, MovieOverlay overlay) {
827ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieMediaItem mediaItem = getMediaItem(mediaItemId);
82805665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi
82905665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        // Remove an existing overlay (if any)
83005665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        final MovieOverlay oldOverlay = mediaItem.getOverlay();
83105665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        if (oldOverlay != null) {
83205665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi            mediaItem.removeOverlay(oldOverlay.getId());
83305665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        }
83405665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi
835ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mediaItem.addOverlay(overlay);
83605665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
837ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
838ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
839ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
840ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Remove the specified overlay
841ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
842ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
843ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param overlayId The overlay id
844ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
845ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void removeOverlay(String mediaItemId, String overlayId) {
846ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieMediaItem mediaItem = getMediaItem(mediaItemId);
847ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mediaItem.removeOverlay(overlayId);
84805665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
849ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
850ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
851ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
852ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Get the specified overlay
853ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
854ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
855ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param overlayId The overlay id
856ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The movie overlay
857ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
858ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieOverlay getOverlay(String mediaItemId, String overlayId) {
859ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieMediaItem mediaItem = getMediaItem(mediaItemId);
860ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mediaItem.getOverlay();
861ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
862ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
863ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
864ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Add the effect
865ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
866ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
867ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param effect The effect
868ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
869ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void addEffect(String mediaItemId, MovieEffect effect) {
870ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieMediaItem mediaItem = getMediaItem(mediaItemId);
87105665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        // Remove an existing effect
87205665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        final MovieEffect oldEffect = mediaItem.getEffect();
87305665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        if (oldEffect != null) {
87405665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi            mediaItem.removeEffect(oldEffect.getId());
87505665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        }
87605665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi
877ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mediaItem.addEffect(effect);
87805665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
879ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
880ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
881ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
882ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Remove the specified effect
883ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
884ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
885ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param effectId The effect id
886ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
887ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void removeEffect(String mediaItemId, String effectId) {
888ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieMediaItem mediaItem = getMediaItem(mediaItemId);
889ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mediaItem.removeEffect(effectId);
89005665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
891ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
892ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
893ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
894ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Get the specified effect
895ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
896ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
897ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param effectId The effect id
898ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The movie effect
899ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
900ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieEffect getEffect(String mediaItemId, String effectId) {
901ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final MovieMediaItem mediaItem = getMediaItem(mediaItemId);
902ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mediaItem.getEffect();
903ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
904ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
905ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
906ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Set the audio tracks
907ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
908ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param audioTracks The audio tracks
909ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
910ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void setAudioTracks(List<MovieAudioTrack> audioTracks) {
911ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mAudioTracks = audioTracks;
91205665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
913ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
914ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
915ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
916ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Add an audio track
917ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
918ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param audioTrack The audio track
919ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
920ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void addAudioTrack(MovieAudioTrack audioTrack) {
921ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mAudioTracks.add(audioTrack);
92205665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
923ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
924ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
925ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
926ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Remove the specified audio track
927ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
928ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param audioTrackId The audio track id
929ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
930ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    void removeAudioTrack(String audioTrackId) {
931ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int count = mAudioTracks.size();
932ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < count; i++) {
933ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieAudioTrack audioTrack = mAudioTracks.get(i);
934ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (audioTrack.getId().equals(audioTrackId)) {
935ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                mAudioTracks.remove(i);
93605665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi                mClean = false;
937ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                break;
938ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
939ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
940ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
941ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
942ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
943ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The audio tracks
944ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
945ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public List<MovieAudioTrack> getAudioTracks() {
946ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return mAudioTracks;
947ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
948ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
949ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
950ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param audioTrackId The audio track id
951ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The audio track
952ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
953ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public MovieAudioTrack getAudioTrack(String audioTrackId) {
954ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (MovieAudioTrack audioTrack : mAudioTracks) {
955ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (audioTrack.getId().equals(audioTrackId)) {
956ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                return audioTrack;
957ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
958ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
959ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
960ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return null;
961ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
962ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
963ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
964ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Compute the begin time for this media item
965ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
966ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id for which we compute the begin time
967ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
968ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The begin time for this media item
969ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
970ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public long getMediaItemBeginTime(String mediaItemId) {
971ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        long beginMs = 0;
972ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int mediaItemsCount = mMediaItems.size();
973ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < mediaItemsCount; i++) {
974ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem mi = mMediaItems.get(i);
975ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mi.getId().equals(mediaItemId)) {
976ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                break;
977ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
978ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
979ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            beginMs += mi.getAppTimelineDuration();
980ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
981ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mi.getEndTransition() != null) {
982ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (i < mediaItemsCount - 1) {
983ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    beginMs -= mi.getEndTransition().getAppDuration();
984ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
985ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
986ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
987ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
988ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return beginMs;
989ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
990ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
991ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
992ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The total duration
993ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
994ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public long computeDuration() {
995ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        long totalDurationMs = 0;
996ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final int mediaItemsCount = mMediaItems.size();
997ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        for (int i = 0; i < mediaItemsCount; i++) {
998ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MovieMediaItem mediaItem = mMediaItems.get(i);
999ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            totalDurationMs += mediaItem.getAppTimelineDuration();
1000ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1001ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mediaItem.getEndTransition() != null) {
1002ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                if (i < mediaItemsCount - 1) {
1003ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    totalDurationMs -= mediaItem.getEndTransition().getAppDuration();
1004ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
1005ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
1006ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
1007ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1008ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        return totalDurationMs;
1009ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
1010ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1011ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
1012ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Render a frame according to the preview aspect ratio and activating all
1013ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * storyboard items relative to the specified time.
1014ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
1015ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param surfaceHolder SurfaceHolder used by the application
1016ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param timeMs time corresponding to the frame to display
1017ce725d3ddbde5bd3e87ad3f6ea17d7c53d6e9c60Gil Dobjanschi     * @param overlayData The overlay data
1018ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
1019ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The accurate time stamp of the frame that is rendered.
1020ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @throws IllegalStateException if a preview or an export is already in
1021ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *             progress
1022ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @throws IllegalArgumentException if time is negative or beyond the
1023ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *             preview duration
1024ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
1025ce725d3ddbde5bd3e87ad3f6ea17d7c53d6e9c60Gil Dobjanschi    public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs,
1026ce725d3ddbde5bd3e87ad3f6ea17d7c53d6e9c60Gil Dobjanschi            VideoEditor.OverlayData overlayData) {
1027ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mVideoEditor != null) {
1028ce725d3ddbde5bd3e87ad3f6ea17d7c53d6e9c60Gil Dobjanschi            return mVideoEditor.renderPreviewFrame(surfaceHolder, timeMs, overlayData);
1029ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
1030ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return 0;
1031ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
1032ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
1033ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1034ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
1035ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Render a frame of a media item.
1036ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
1037ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param surfaceHolder SurfaceHolder used by the application
1038ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param mediaItemId The media item id
1039ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param timeMs time corresponding to the frame to display
1040ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
1041ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The accurate time stamp of the frame that is rendered .
1042ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @throws IllegalStateException if a preview or an export is already in
1043ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *             progress
1044ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @throws IllegalArgumentException if time is negative or beyond the
1045ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *             preview duration
1046ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
1047ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public long renderMediaItemFrame(SurfaceHolder surfaceHolder, String mediaItemId,
1048ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            long timeMs) {
1049ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mVideoEditor != null) {
1050ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final MediaVideoItem mediaItem =
1051ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                (MediaVideoItem)mVideoEditor.getMediaItem(mediaItemId);
1052ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (mediaItem != null) {
1053ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                return mediaItem.renderFrame(surfaceHolder, timeMs);
1054ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            } else {
1055ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                return -1;
1056ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
1057ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
1058ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return 0;
1059ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
1060ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
1061ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1062ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
1063ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Start the preview of all the storyboard items applied on all MediaItems
1064ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * This method does not block (does not wait for the preview to complete).
1065ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * The PreviewProgressListener allows to track the progress at the time
1066ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * interval determined by the callbackAfterFrameCount parameter. The
1067ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * SurfaceHolder has to be created and ready for use before calling this
1068ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * method. The method is a no-op if there are no MediaItems in the
1069ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * storyboard.
1070ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
1071ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param surfaceHolder SurfaceHolder where the preview is rendered.
1072ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param fromMs The time (relative to the timeline) at which the preview
1073ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *            will start
1074ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param toMs The time (relative to the timeline) at which the preview will
1075ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *            stop. Use -1 to play to the end of the timeline
1076ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param loop true if the preview should be looped once it reaches the end
1077ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param callbackAfterFrameCount The listener interface should be invoked
1078ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *            after the number of frames specified by this parameter.
1079ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param listener The listener which will be notified of the preview
1080ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *            progress
1081ce725d3ddbde5bd3e87ad3f6ea17d7c53d6e9c60Gil Dobjanschi     *
1082ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @throws IllegalArgumentException if fromMs is beyond the preview duration
1083ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @throws IllegalStateException if a preview or an export is already in
1084ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *             progress
1085ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
1086ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public void startPreview(SurfaceHolder surfaceHolder, long fromMs, long toMs, boolean loop,
1087ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            int callbackAfterFrameCount, PreviewProgressListener listener) {
1088ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mVideoEditor != null) {
1089ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            mVideoEditor.startPreview(surfaceHolder, fromMs, toMs, loop, callbackAfterFrameCount,
1090ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    listener);
1091ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
1092ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
1093ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1094ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
1095ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Stop the current preview. This method blocks until ongoing preview is
1096ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * stopped. Ignored if there is no preview running.
1097ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
1098ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return The accurate current time when stop is effective expressed in
1099ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *         milliseconds
1100ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
1101ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public long stopPreview() {
1102ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mVideoEditor != null) {
1103ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return mVideoEditor.stopPreview();
1104ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } else {
1105ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return 0;
1106ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
1107ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
1108ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1109ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
11108180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi     * Clear the surface
11118180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi     *
11128180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi     * @param surfaceHolder SurfaceHolder where the preview is rendered.
11138180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi     */
11148180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi    public void clearSurface(SurfaceHolder surfaceHolder) {
11158180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi        if (mVideoEditor != null) {
11168180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi            mVideoEditor.clearSurface(surfaceHolder);
11178180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi        }
11188180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi    }
11198180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi
11208180711b58d53da187fbcf47c8eae03a04e88d34Gil Dobjanschi    /**
1121ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Release the project
1122ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
1123ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public void release() {
1124ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
1125ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1126ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
1127f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     * Add a new download to the project
1128f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     *
1129f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     * @param mediaUri The media URI
1130f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     * @param mimeType The mime type
1131f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     * @param filename The local filename
1132f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     */
1133f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    public void addDownload(String mediaUri, String mimeType, String filename) {
1134f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        mDownloads.add(new Download(mediaUri, mimeType, filename, System.currentTimeMillis()));
113505665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi        mClean = false;
1136f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    }
1137f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
1138f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    /**
1139f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     * Remove a download
1140f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     *
1141f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     * @param mediaUri The media URI
1142f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     */
1143f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    public void removeDownload(String mediaUri) {
1144f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        final int count = mDownloads.size();
1145f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        for (int i = 0; i < count; i++) {
1146f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            final Download download = mDownloads.get(i);
1147f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            final String uri = download.getMediaUri();
1148f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            if (mediaUri.equals(uri)) {
1149f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                // Delete the file associated with the download
1150f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                final String filename = download.getFilename();
1151f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                new File(filename).delete();
1152f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
1153f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                // Remove the download from the list
1154f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                mDownloads.remove(i);
115505665b0d312798e49b51d8a7ed9b4de328b6b86fGil Dobjanschi                mClean = false;
1156f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                break;
1157f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            }
1158f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        }
1159f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    }
1160f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
1161f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    /**
1162f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     * @return The list of downloads
1163f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi     */
1164f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    public List<Download> getDownloads() {
1165f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        return mDownloads;
1166f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    }
1167f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
1168f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi    /**
1169ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Load metadata from file
1170ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
1171ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param videoEditor The video editor
1172ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @param projectPath The project path
1173ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     *
1174ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * @return A new instance of the VideoEditorProject
1175ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
1176ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public static VideoEditorProject fromXml(VideoEditor videoEditor, String projectPath)
1177ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            throws XmlPullParserException, FileNotFoundException, IOException {
1178ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final File file = new File(projectPath, PROJECT_METADATA_FILENAME);
1179ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final FileInputStream fis = new FileInputStream(file);
1180f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        final List<Download> downloads = new ArrayList<Download>();
1181ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        try {
1182ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            // Load the metadata
1183ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            final XmlPullParser parser = Xml.newPullParser();
1184ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            parser.setInput(fis, "UTF-8");
1185ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            int eventType = parser.getEventType();
1186ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1187ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            String projectName = null;
1188ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            String themeId = null;
1189ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            Uri exportedMovieUri = null;
1190ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            long lastSaved = 0;
1191ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            long playheadPosMs = 0;
1192ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            long durationMs = 0;
1193ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            int zoomLevel = DEFAULT_ZOOM_LEVEL;
1194ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            while (eventType != XmlPullParser.END_DOCUMENT) {
1195ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                String name = null;
1196ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                switch (eventType) {
1197ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    case XmlPullParser.START_TAG: {
1198ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        name = parser.getName();
1199ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        if (name.equalsIgnoreCase(TAG_PROJECT)) {
1200ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                            projectName = parser.getAttributeValue("", ATTR_NAME);
1201ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                            themeId = parser.getAttributeValue("", ATTR_THEME);
1202ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                            lastSaved = Long.parseLong(parser.getAttributeValue("", ATTR_SAVED));
1203ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                            playheadPosMs = Long.parseLong(parser.getAttributeValue("",
1204ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                                    ATTR_PLAYHEAD_POSITION));
1205ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                            durationMs = Long.parseLong(parser.getAttributeValue("",
1206ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                                    ATTR_DURATION));
1207ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                            zoomLevel = Integer.parseInt(parser.getAttributeValue("",
1208ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                                    ATTR_ZOOM_LEVEL));
1209ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        } else if (name.equalsIgnoreCase(TAG_MOVIE)) {
1210ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                            exportedMovieUri = Uri.parse(parser.getAttributeValue("", ATTR_URI));
1211f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                        } else if (name.equalsIgnoreCase(TAG_DOWNLOAD)) {
1212f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                            downloads.add(new Download(parser.getAttributeValue("", ATTR_URI),
1213f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                                    parser.getAttributeValue("", ATTR_MIME),
1214f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                                    parser.getAttributeValue("", ATTR_FILENAME),
1215f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                                    Long.parseLong(parser.getAttributeValue("", ATTR_TIME))));
1216ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        }
1217f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi
1218ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        break;
1219ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    }
1220ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1221ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    default: {
1222ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                        break;
1223ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                    }
1224ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                }
1225ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                eventType = parser.next();
1226ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
1227ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1228ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            return new VideoEditorProject(videoEditor, projectPath, projectName, lastSaved,
1229f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi                    playheadPosMs, durationMs, zoomLevel, exportedMovieUri, themeId, downloads);
1230ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        } finally {
1231ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            if (fis != null) {
1232ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                fis.close();
1233ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            }
1234ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
1235ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
1236ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1237ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    /**
1238ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     * Save the content to XML
1239ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi     */
1240ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    public void saveToXml() throws IOException {
1241ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        // Save the project metadata
1242ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final XmlSerializer serializer = Xml.newSerializer();
1243ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final StringWriter writer = new StringWriter();
1244ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        serializer.setOutput(writer);
1245ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        serializer.startDocument("UTF-8", true);
1246ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        serializer.startTag("", TAG_PROJECT);
1247ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mProjectName != null) {
1248ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            serializer.attribute("", ATTR_NAME, mProjectName);
1249ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
1250ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mTheme != null) {
1251ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            serializer.attribute("", ATTR_THEME, mTheme);
1252ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
1253ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1254ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        serializer.attribute("", ATTR_PLAYHEAD_POSITION, Long.toString(mPlayheadPosMs));
1255ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        serializer.attribute("", ATTR_DURATION, Long.toString(computeDuration()));
1256ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        serializer.attribute("", ATTR_ZOOM_LEVEL, Integer.toString(mZoomLevel));
1257ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1258ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        mLastSaved = System.currentTimeMillis();
1259ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        serializer.attribute("", ATTR_SAVED, Long.toString(mLastSaved));
1260ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        if (mExportedMovieUri != null) {
1261ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            serializer.startTag("", TAG_MOVIE);
1262ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            serializer.attribute("", ATTR_URI, mExportedMovieUri.toString());
1263ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi            serializer.endTag("", TAG_MOVIE);
1264ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        }
1265ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1266f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        for (Download download : mDownloads) {
1267f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            serializer.startTag("", TAG_DOWNLOAD);
1268f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            serializer.attribute("", ATTR_URI, download.getMediaUri());
1269f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            serializer.attribute("", ATTR_MIME, download.getMimeType());
1270f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            serializer.attribute("", ATTR_FILENAME, download.getFilename());
1271f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            serializer.attribute("", ATTR_TIME, Long.toString(download.getTime()));
1272f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi            serializer.endTag("", TAG_DOWNLOAD);
1273f69cd2d4db2fb4f4c268e33e9728773480b298a4Gil Dobjanschi        }
1274ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        serializer.endTag("", TAG_PROJECT);
1275ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        serializer.endDocument();
1276ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi
1277ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        // Save the metadata XML file
1278ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        final FileOutputStream out = new FileOutputStream(new File(mVideoEditor.getPath(),
1279ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi                PROJECT_METADATA_FILENAME));
1280ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        out.write(writer.toString().getBytes("UTF-8"));
1281ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        out.flush();
1282ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi        out.close();
1283ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi    }
1284ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi}
1285