
public class EncodeExample {

    /*
     * Global IDs to work around samsung tab manifest receivers not picking up broadcast actions
     * if their process isn't already running
     */
    public static final String ENCODER_PACKAGE_NAME = "com.fognl.android.service.looksee.encoder";
    public static final String ENCODER_RECEIVER = ENCODER_PACKAGE_NAME + ".LookSeeEncoderReceiver";

    /*
     * Broadcast actions
     */
    public static final String
        ACTION_ENCODE_TO_VIDEO = "com.fognl.android.apps.private.ENCODE_TO_VIDEO"
    ,   ACTION_RIP_FRAMES = "com.fognl.android.apps.private.RIP_FRAMES"
    ,   ACTION_EXTRACT_AUDIO = "com.fognl.android.apps.private.EXTRACT_AUDIO"
    ,   ACTION_CONVERT_VIDEO = "com.fognl.android.apps.private.CONVERT_VIDEO"
    ,   ACTION_SET_STATUS_TEXT = "com.fognl.android.apps.private.SET_STATUS_TEXT"
    ,   EVENT_ERROR = "com.fognl.android.apps.private.ENCODER_ERROR"
    ,   EVENT_COMPLETE = "com.fognl.android.apps.private.ENCODER_COMPLETE"
    ,   EVENT_HEARTBEAT = "com.fognl.android.apps.private.ENCODER_HEARTBEAT"
    ;
    
    /*
     * Extras
     */
    public static final String
        EXTRA_INPUT_PATH = "extra.input.path"
    ,   EXTRA_OUTPUT_PATH = "extra.output.path"
    ,   EXTRA_AUDIO_PATH = "extra.audio.path"
    ,   EXTRA_WIDTH = "extra.width"
    ,   EXTRA_HEIGHT = "extra.height"
    ,   EXTRA_FRAME_RATE = "extra.frame.rate"
    ,   EXTRA_ERROR = "extra.error"
    ,   EXTRA_START_ACTION = "extra.start.action"
    ,   EXTRA_FRAME_INDEX = "extra.frame.index"
    ,   EXTRA_FRAME_COUNT = "extra.frame.count"
    ,   EXTRA_PERCENT_COMPLETE = "extra.percent.complete"
    ,   EXTRA_STATUS_TEXT = "extra.status.text"
    ,   EXTRA_SUPPORTED_FORMAT_LINES = "extra.supported.format.lines"
    ,   EXTRA_RESULT_CODE = "extra.result.code"
    ;
    

    /** Find the encoder service on the device. Normally this wouldn't be necessary, you could just send
        the ACTION_ENCODE_TO_VIDEO broadcast intent. However, a manifest receiver in the Encoder on a 
        Samsung Galaxy Tab 10.1 was tested and shown not to receive the message if the encoder's process
        isn't already running. The workaround is to query the receiver by full name to ensure it's available
        on the device.
      */
    public static Intent findEncoderService(Context context) {
        final Intent intent = new Intent();
        intent.setComponent(new ComponentName(
                ENCODER_PACKAGE_NAME,
                ENCODER_RECEIVER));

        List<ResolveInfo> list = context.getPackageManager().queryBroadcastReceivers(intent, 0);
        return (list.size() > 0) ? intent : null;
    }
    
    /** Return an IntentFilter that a BroadcastReciever can use to be notified of events emitted by the encoder. */
    public static IntentFilter makeEventIntentFilter() {
        IntentFilter filter = new IntentFilter();
        // Tne encoder is finished.
        filter.addAction(LookSeeConstants.EVENT_COMPLETE);
        // The encoder had an error.
        filter.addAction(LookSeeConstants.EVENT_ERROR);
        // The encoder sent an update.
        filter.addAction(LookSeeConstants.EVENT_HEARTBEAT);
        // The encoder sent an update containing status text. extra.status.text contains the text.
        filter.addAction(LookSeeConstants.ACTION_SET_STATUS_TEXT);

        return filter;
    }

    /**
     Encode a sequence of images into a video file. The images must be
     named sequentially from first to last as 000000001.jpg, 000000002.jpg, and so on,
     with no gaps in the numeric sequence. The encoder will use "%09d.jpg" as the filename
     specifier.
     
     @param imagePath The directory containing the images.
     @param outFile The output file to create.
     @param audioFile An audio file to attach to the video (wav only, no spaces in the filename)
     @param width Video width
     @param height Video height
     @param frameRate The frame rate to encode the video at
     @param totalFrames The total number of files in imagePath.
     */
    public void encodeImagesToVideo(File imagePath, File outFile,
            File audioFile, int width, int height, int frameRate,
            int totalFrames) {
        final Intent intent = findEncoderService(mContext);

        if (intent != null) {
            intent.setAction(ACTION_ENCODE_TO_VIDEO);
            intent
                .putExtra(EXTRA_INPUT_PATH, imagePath.getAbsolutePath())
                .putExtra(EXTRA_OUTPUT_PATH, outFile.getAbsolutePath())
                .putExtra(EXTRA_AUDIO_PATH, ((audioFile != null) ? audioFile.getAbsolutePath() : ""))
                .putExtra(EXTRA_WIDTH, width)
                .putExtra(EXTRA_HEIGHT, height)
                .putExtra(EXTRA_FRAME_RATE, frameRate)
                .putExtra(EXTRA_FRAME_COUNT, totalFrames)
                ;

            mContext.sendBroadcast(intent);
        }
        else {
            Log.w(TAG, "Cannot find the encoder service");
        }
    }
}


