0

我想将 MOV 文件转换为 AVI 文件作为我项目的一部分。MOV 正在从一组 JPEG 文件中正确转换。但我无法将 MOV 转换为 AVI。它说输出 .avi 文件是 0 字节。有人可以帮忙吗?

这是源代码:

public class Transcode implements ControllerListener, DataSinkListener {

    /**
     * Given a source media locator, destination media locator and
     * an array of formats, this method will transcode the source to
     * the dest into the specified formats.
     */
    public boolean doIt(MediaLocator inML, MediaLocator outML, Format fmts[],
        int start, int end) {

    Processor p;

    try {
        p = Manager.createProcessor(inML);
    } catch (Exception e) {
        System.err.println("Cannot create a processor from the given url: " + e);
        return false;
    }

    p.addControllerListener(this);

    // Put the Processor into configured state.
    p.configure();
    if (!waitForState(p, p.Configured)) {
        System.err.println("Failed to configure the processor.");
        return false;
    }

    // Set the output content descriptor based on the media locator.
    setContentDescriptor(p, outML);

    // Program the tracks to the given output formats.
    if (!setTrackFormats(p, fmts))
        return false;

    // We are done with programming the processor.  Let's just
    // realize the it.
    p.realize();
    if (!waitForState(p, p.Realized)) {
        System.err.println("Failed to realize the processor.");
        return false;
    }

    // Set the JPEG quality to .5.
    setJPEGQuality(p, 0.5f);

    // Now, we'll need to create a DataSink.
    DataSink dsink;
    if ((dsink = createDataSink(p, outML)) == null) {
        System.err.println("Failed to create a DataSink for the given output MediaLocator: " + outML);
        return false;
    }

    dsink.addDataSinkListener(this);
    fileDone = false;

    // Set the start time if there's one set.
    if (start > 0)
        p.setMediaTime(new Time((double)start));

    // Set the stop time if there's one set.
    if (end > 0)
        p.setStopTime(new Time((double)end));

    // OK, we can now start the actual transcoding.
    try {
        p.start();
        dsink.start();
    } catch (IOException e) {
        System.err.println("IO error during transcoding");
        return false;
    }

    // Wait for EndOfStream event.
    waitForFileDone();

    // Cleanup.
    try {
        dsink.close();
    } catch (Exception e) {}
    p.removeControllerListener(this);

    return true;
    }


    /**
     * Set the content descriptor based on the given output MediaLocator.
     */
    void setContentDescriptor(Processor p, MediaLocator outML) {

    ContentDescriptor cd;

    // If the output file maps to a content type,
    // we'll try to set it on the processor.

    if ((cd = fileExtToCD(outML.getRemainder())) != null) {
        if ((p.setContentDescriptor(cd)) == null) {

        // The processor does not support the output content
        // type.  But we can set the content type to RAW and
        // see if any DataSink supports it.

        p.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW));
        }
    }
    }


    /**
     * Set the target transcode format on the processor.
     */
    boolean setTrackFormats(Processor p, Format fmts[]) {

    if (fmts.length == 0)
        return true;

    TrackControl tcs[];

    if ((tcs = p.getTrackControls()) == null) {
        // The processor does not support any track control.
        System.err.println("The Processor cannot transcode the tracks to the given formats");
        return false;
    }

    for (int i = 0; i < fmts.length; i++) {

        System.err.println("- set track format to: " + fmts[i]);

        if (!setEachTrackFormat(p, tcs, fmts[i])) {
        System.err.println("Cannot transcode any track to: " + fmts[i]);
        return false;
        }
    }

    return true;
    }


    /**
     * We'll loop through the tracks and try to find a track
     * that can be converted to the given format.
     */
    boolean setEachTrackFormat(Processor p, TrackControl tcs[], Format fmt) {

    Format supported[];
    Format f;

    for (int i = 0; i < tcs.length; i++) {

        supported = tcs[i].getSupportedFormats();

        if (supported == null)
        continue;

        for (int j = 0; j < supported.length; j++) {

        if (fmt.matches(supported[j]) &&
            (f = fmt.intersects(supported[j])) != null &&
            tcs[i].setFormat(f) != null) {

            // Success.
            return true;
        }
        }
    }

    return false;
    }


    /**
     * Setting the encoding quality to the specified value on the JPEG encoder.
     * 0.5 is a good default.
     */
    void setJPEGQuality(Player p, float val) {

    Control cs[] = p.getControls();
    QualityControl qc = null;
    VideoFormat jpegFmt = new VideoFormat(VideoFormat.JPEG);

    // Loop through the controls to find the Quality control for
    // the JPEG encoder.
    for (int i = 0; i < cs.length; i++) {

        if (cs[i] instanceof QualityControl &&
        cs[i] instanceof Owned) {
        Object owner = ((Owned)cs[i]).getOwner();

        // Check to see if the owner is a Codec.
        // Then check for the output format.
        if (owner instanceof Codec) {
            Format fmts[] = ((Codec)owner).getSupportedOutputFormats(null);
            for (int j = 0; j < fmts.length; j++) {
            if (fmts[j].matches(jpegFmt)) {
                qc = (QualityControl)cs[i];
                    qc.setQuality(val);
                System.err.println("- Set quality to " +
                    val + " on " + qc);
                break;
            }
            }
        }
        if (qc != null)
            break;
        }
    }
    }


    /**
     * Create the DataSink.
     */
    DataSink createDataSink(Processor p, MediaLocator outML) {

    DataSource ds;

    if ((ds = p.getDataOutput()) == null) {
        System.err.println("Something is really wrong: the processor does not have an output DataSource");
        return null;
    }

    DataSink dsink;

    try {
        dsink = Manager.createDataSink(ds, outML);
        dsink.open();
    } catch (Exception e) {
        System.err.println("Cannot create the DataSink: " + e);
        return null;
    }

    return dsink;
    }


    Object waitSync = new Object();
    boolean stateTransitionOK = true;

    /**
     * Block until the processor has transitioned to the given state.
     * Return false if the transition failed.
     */
    boolean waitForState(Processor p, int state) {
    synchronized (waitSync) {
        try {
        while (p.getState() < state && stateTransitionOK)
            waitSync.wait();
        } catch (Exception e) {}
    }
    return stateTransitionOK;
    }


    /**
     * Controller Listener.
     */
    public void controllerUpdate(ControllerEvent evt) {

    if (evt instanceof ConfigureCompleteEvent ||
        evt instanceof RealizeCompleteEvent ||
        evt instanceof PrefetchCompleteEvent) {
        synchronized (waitSync) {
        stateTransitionOK = true;
        waitSync.notifyAll();
        }
    } else if (evt instanceof ResourceUnavailableEvent) {
        synchronized (waitSync) {
        stateTransitionOK = false;
        waitSync.notifyAll();
        }
    } else if (evt instanceof EndOfMediaEvent) {
        evt.getSourceController().close();
    } else if (evt instanceof MediaTimeSetEvent) {
        System.err.println("- mediaTime set: " +
        ((MediaTimeSetEvent)evt).getMediaTime().getSeconds());
    } else if (evt instanceof StopAtTimeEvent) {
        System.err.println("- stop at time: " +
        ((StopAtTimeEvent)evt).getMediaTime().getSeconds());
        evt.getSourceController().close();
    }
    }


    Object waitFileSync = new Object();
    boolean fileDone = false;
    boolean fileSuccess = true;

    /**
     * Block until file writing is done.
     */
    boolean waitForFileDone() {
    System.err.print("  ");
    synchronized (waitFileSync) {
        try {
        while (!fileDone) {
            waitFileSync.wait(1000);
        }
        } catch (Exception e) {}
    }
    return fileSuccess;
    }


    /**
     * Event handler for the file writer.
     */
    public void dataSinkUpdate(DataSinkEvent evt) {

    if (evt instanceof EndOfStreamEvent) {
        synchronized (waitFileSync) {
        fileDone = true;
        waitFileSync.notifyAll();
        }
    } else if (evt instanceof DataSinkErrorEvent) {
        synchronized (waitFileSync) {
        fileDone = true;
        fileSuccess = false;
        waitFileSync.notifyAll();
        }
    }
    }


    /**
     * Convert a file name to a content type.  The extension is parsed
     * to determine the content type.
     */
    ContentDescriptor fileExtToCD(String name) {

    String ext;
    int p;

    // Extract the file extension.
    if ((p = name.lastIndexOf('.')) < 0)
        return null;

    ext = (name.substring(p + 1)).toLowerCase();

    String type;

    // Use the MimeManager to get the mime type from the file extension.
    if ( ext.equals("mp3")) {
        type = FileTypeDescriptor.MPEG_AUDIO;
    } else {
        if ((type = com.sun.media.MimeManager.getMimeType(ext)) == null)
        return null;
        type = ContentDescriptor.mimeTypeToPackageName(type);
    }

    return new FileTypeDescriptor(type);
    }

    /**
     * Create a media locator from the given string.
     */
    public static MediaLocator createMediaLocator(String url) {

    MediaLocator ml;

    if (url.indexOf(":") > 0 && (ml = new MediaLocator(url)) != null)
        return ml;

    if (url.startsWith(File.separator)) {
        if ((ml = new MediaLocator("file:" + url)) != null)
        return ml;
    } else {
        String file = "file:" + System.getProperty("user.dir") + File.separator + url;
        if ((ml = new MediaLocator(file)) != null)
        return ml;
    }

    return null;
    }


    /**
     * Parse the audio format specifier and generate an AudioFormat.
     * A valid audio format specifier is of the form:
     * [encoding]:[rate]:[sizeInBits]:[channels]:[big|little]:[signed|unsigned]
     */
    public static Format parseAudioFormat(String fmtStr) {

    int rate, bits, channels, endian, signed;

    String encodeStr = null, rateStr = null,
        bitsStr = null, channelsStr = null,
        endianStr = null, signedStr = null;

    // Parser the media locator to extract the requested format.

    if (fmtStr != null && fmtStr.length() > 0) {
        while (fmtStr.length() > 1 && fmtStr.charAt(0) == ':')
        fmtStr = fmtStr.substring(1);

        // Now see if there's a encode rate specified.
        int off = fmtStr.indexOf(':');
        if (off == -1) {
        if (!fmtStr.equals(""))
            encodeStr = fmtStr;
        } else {
        encodeStr = fmtStr.substring(0, off);
        fmtStr = fmtStr.substring(off + 1);
        // Now see if there's a sample rate specified
        off = fmtStr.indexOf(':');
        if (off == -1) {
            if (!fmtStr.equals(""))
            rateStr = fmtStr;
        } else {
            rateStr = fmtStr.substring(0, off);
            fmtStr = fmtStr.substring(off + 1);
            // Now see if there's a size specified
            off = fmtStr.indexOf(':');
            if (off == -1) {
            if (!fmtStr.equals(""))
                bitsStr = fmtStr;
            } else {
            bitsStr = fmtStr.substring(0, off);
            fmtStr = fmtStr.substring(off + 1);
            // Now see if there's channels specified.
            off = fmtStr.indexOf(':');
            if (off == -1) {
                if (!fmtStr.equals(""))
                channelsStr = fmtStr;
            } else {
                channelsStr = fmtStr.substring(0, off);
                fmtStr = fmtStr.substring(off + 1);
                // Now see if there's endian specified.
                off = fmtStr.indexOf(':');
                if (off == -1) {
                if (!fmtStr.equals(""))
                        endianStr = fmtStr.substring(off + 1);
                } else {
                    endianStr = fmtStr.substring(0, off);
                if (!fmtStr.equals(""))
                        signedStr = fmtStr.substring(off + 1);
                }
            }
           }
        }
        }
    }

    // Sample Rate
    rate = AudioFormat.NOT_SPECIFIED;
    if (rateStr != null) {
        try {
        Integer integer = Integer.valueOf(rateStr);
        if (integer != null)
            rate = integer.intValue();
        } catch (Throwable t) { }
    }

    // Sample Size
    bits = AudioFormat.NOT_SPECIFIED;
    if (bitsStr != null) {
        try {
        Integer integer = Integer.valueOf(bitsStr);
        if (integer != null)
            bits = integer.intValue();
        } catch (Throwable t) { }
    }

    // # of channels
    channels = AudioFormat.NOT_SPECIFIED;
    if (channelsStr != null) {
        try {
        Integer integer = Integer.valueOf(channelsStr);
        if (integer != null)
            channels = integer.intValue();
        } catch (Throwable t) { }
    }

    // Endian
        endian = AudioFormat.NOT_SPECIFIED;
    if (endianStr != null) {
        if (endianStr.equalsIgnoreCase("big"))
            endian = AudioFormat.BIG_ENDIAN;
        else if (endianStr.equalsIgnoreCase("little"))
        endian = AudioFormat.LITTLE_ENDIAN;
    }

    // Signed
        signed = AudioFormat.NOT_SPECIFIED;
    if (signedStr != null) {
        if (signedStr.equalsIgnoreCase("signed"))
        signed = AudioFormat.SIGNED;
        else if (signedStr.equalsIgnoreCase("unsigned"))
            signed = AudioFormat.UNSIGNED;
    }

    return new AudioFormat(encodeStr, rate, bits, channels, endian, signed);
    }


    /**
     * Parse the video format specifier and generate an VideoFormat.
     * A valid video format specifier is of the form:
     * [encoding]:[widthXheight]
     */
    public static Format parseVideoFormat(String fmtStr) {

    String encodeStr = null, sizeStr = null;

    // Parser the media locator to extract the requested format.

    if (fmtStr != null && fmtStr.length() > 0) {
        while (fmtStr.length() > 1 && fmtStr.charAt(0) == ':')
        fmtStr = fmtStr.substring(1);

        // Now see if there's a encode rate specified.
        int off = fmtStr.indexOf(':');
        if (off == -1) {
        if (!fmtStr.equals(""))
            encodeStr = fmtStr;
        } else {
        encodeStr = fmtStr.substring(0, off);
        sizeStr = fmtStr.substring(off + 1);
        }
    }

    if (encodeStr == null || encodeStr.equals(""))
//      prUsage();

    if (sizeStr == null)
        return new VideoFormat(encodeStr);

    int width = 320, height = 240;

    int off = sizeStr.indexOf('X');
    if (off == -1)
        off = sizeStr.indexOf('x');

    if (off == -1) {
        System.err.println("Video dimension is not correctly specified: " + sizeStr);
//      prUsage();
    } else {
        String widthStr = sizeStr.substring(0, off);
        String heightStr = sizeStr.substring(off + 1);

        try {
        Integer integer = Integer.valueOf(widthStr);
        if (integer != null)
            width = integer.intValue();
        integer = Integer.valueOf(heightStr);
        if (integer != null)
            height = integer.intValue();
        } catch (Throwable t) {
//      prUsage();
        }

        return new VideoFormat(encodeStr,
                new Dimension(width, height),
                VideoFormat.NOT_SPECIFIED, // maxDataLen
                null,              // data class
                VideoFormat.NOT_SPECIFIED  // FrameRate
                );
    }

    return null;
    }
}
4

0 回答 0