Search in sources :

Example 1 with DiskManagerFileInfoURL

use of com.biglybt.core.download.DiskManagerFileInfoURL in project BiglyBT by BiglySoftware.

the class TranscodeQueueImpl method process.

protected boolean process(final TranscodeJobImpl job) {
    TranscodePipe pipe = null;
    current_job = job;
    DeviceImpl device = job.getDevice();
    device.setTranscoding(true);
    try {
        job.starts();
        TranscodeProvider provider = job.getProfile().getProvider();
        final TranscodeException[] error = { null };
        TranscodeProfile profile = job.getProfile();
        final TranscodeFileImpl transcode_file = job.getTranscodeFile();
        TranscodeProviderAnalysis provider_analysis;
        boolean xcode_required;
        if (provider == null) {
            xcode_required = false;
            provider_analysis = null;
        } else {
            provider_analysis = analyse(job);
            xcode_required = provider_analysis.getBooleanProperty(TranscodeProviderAnalysis.PT_TRANSCODE_REQUIRED);
            int tt_req;
            if (job.isStream()) {
                // already advertised as a transcoded asset so no option not to
                // transcode (as name/format would change if decided not to transcode and then
                // this would confuse the clients)
                tt_req = TranscodeTarget.TRANSCODE_ALWAYS;
            } else {
                tt_req = job.getTranscodeRequirement();
                if (device instanceof TranscodeTarget) {
                    if (provider_analysis.getLongProperty(TranscodeProviderAnalysis.PT_VIDEO_HEIGHT) == 0) {
                        if (((TranscodeTarget) device).isAudioCompatible(transcode_file)) {
                            tt_req = TranscodeTarget.TRANSCODE_NEVER;
                        }
                    }
                }
            }
            if (tt_req == TranscodeTarget.TRANSCODE_NEVER) {
                xcode_required = false;
            } else if (tt_req == TranscodeTarget.TRANSCODE_ALWAYS) {
                xcode_required = true;
                provider_analysis.setBooleanProperty(TranscodeProviderAnalysis.PT_FORCE_TRANSCODE, true);
            }
        }
        if (xcode_required) {
            final AESemaphore xcode_sem = new AESemaphore("xcode:proc");
            final TranscodeProviderJob[] provider_job = { null };
            TranscodeProviderAdapter xcode_adapter = new TranscodeProviderAdapter() {

                private boolean resolution_updated;

                private final int ETA_AVERAGE_SIZE = 10;

                private int last_eta;

                private int eta_samples;

                private Average eta_average = AverageFactory.MovingAverage(ETA_AVERAGE_SIZE);

                private int last_percent;

                private long initial_file_downloaded = job.getFile().getDownloaded();

                private long file_size = job.getFile().getLength();

                @Override
                public void updateProgress(int percent, int eta_secs, int new_width, int new_height) {
                    last_eta = eta_secs;
                    last_percent = percent;
                    TranscodeProviderJob prov_job = provider_job[0];
                    if (prov_job == null) {
                        return;
                    }
                    int job_state = job.getState();
                    if (job_state == TranscodeJob.ST_CANCELLED || job_state == TranscodeJob.ST_REMOVED) {
                        prov_job.cancel();
                    } else if (paused || job_state == TranscodeJob.ST_PAUSED) {
                        prov_job.pause();
                    } else {
                        if (job_state == TranscodeJob.ST_RUNNING) {
                            prov_job.resume();
                        }
                        job.updateProgress(percent, eta_secs);
                        prov_job.setMaxBytesPerSecond(max_bytes_per_sec);
                        if (!resolution_updated) {
                            if (new_width > 0 && new_height > 0) {
                                transcode_file.setResolution(new_width, new_height);
                                resolution_updated = true;
                            }
                        }
                    }
                }

                @Override
                public void streamStats(long connect_rate, long write_speed) {
                    if (Constants.isOSX && job.getEnableAutoRetry() && job.canUseDirectInput() && job.getAutoRetryCount() == 0) {
                        if (connect_rate > 5 && last_percent < 100) {
                            long eta = (long) eta_average.update(last_eta);
                            eta_samples++;
                            if (eta_samples >= ETA_AVERAGE_SIZE) {
                                long total_time = (eta * 100) / (100 - last_percent);
                                long total_write = total_time * write_speed;
                                DiskManagerFileInfo file = job.getFile();
                                long length = file.getLength();
                                if (length > 0) {
                                    double over_write = ((double) total_write) / length;
                                    if (over_write > 5.0) {
                                        failed(new TranscodeException("Overwrite limit exceeded, abandoning transcode"));
                                        provider_job[0].cancel();
                                    }
                                }
                            }
                        } else {
                            eta_samples = 0;
                        }
                    }
                }

                @Override
                public void failed(TranscodeException e) {
                    try {
                        if (error[0] == null) {
                            error[0] = e;
                        }
                        if (e.isRetryDisabled()) {
                            job.setEnableAutoRetry(false);
                        }
                    } finally {
                        xcode_sem.release();
                    }
                }

                @Override
                public void complete() {
                    try {
                        // sanity check: for incomplete files at the start of the process ensure that they have completed
                        long current_downloaded = job.getFile().getDownloaded();
                        if (file_size > 0 && initial_file_downloaded < file_size && current_downloaded < file_size) {
                            if (error[0] == null) {
                                // actually this ain't so simple as we stream data prior to hash check completion (otherwise for
                                // large piece sizes we could be waiting for 4MB to complete downloading before playback)
                                // and getDownloaded() only returns the verified data size
                                long contiguous_downloaded = 0;
                                try {
                                    DiskManagerFileInfo _file_info = job.getFile();
                                    Download download = _file_info.getDownload();
                                    com.biglybt.core.disk.DiskManagerFileInfo file_info = PluginCoreUtils.unwrap(_file_info);
                                    TOTorrentFile torrent_file = file_info.getTorrentFile();
                                    TOTorrent torrent = torrent_file.getTorrent();
                                    TOTorrentFile[] torrent_files = torrent.getFiles();
                                    long byte_start = 0;
                                    for (TOTorrentFile tf : torrent_files) {
                                        if (tf == torrent_file) {
                                            break;
                                        }
                                        byte_start += tf.getLength();
                                    }
                                    DiskManager dm = download.getDiskManager();
                                    if (dm == null) {
                                        throw (new Exception("Download stopped"));
                                    }
                                    DiskManagerPiece[] pieces = PluginCoreUtils.unwrap(dm).getPieces();
                                    long piece_size = torrent.getPieceLength();
                                    int first_piece_index = (int) (byte_start / piece_size);
                                    int first_piece_offset = (int) (byte_start % piece_size);
                                    int last_piece_index = torrent_file.getLastPieceNumber();
                                    DiskManagerPiece first_piece = pieces[first_piece_index];
                                    if (!first_piece.isDone()) {
                                        boolean[] blocks = first_piece.getWritten();
                                        if (blocks == null) {
                                            if (first_piece.isDone()) {
                                                contiguous_downloaded = first_piece.getLength() - first_piece_offset;
                                            }
                                        } else {
                                            int piece_offset = 0;
                                            for (int j = 0; j < blocks.length; j++) {
                                                if (blocks[j]) {
                                                    int block_size = first_piece.getBlockSize(j);
                                                    piece_offset = piece_offset + block_size;
                                                    if (contiguous_downloaded == 0) {
                                                        if (piece_offset > first_piece_offset) {
                                                            contiguous_downloaded = piece_offset - first_piece_offset;
                                                        }
                                                    } else {
                                                        contiguous_downloaded += block_size;
                                                    }
                                                } else {
                                                    break;
                                                }
                                            }
                                        }
                                    } else {
                                        contiguous_downloaded = first_piece.getLength() - first_piece_offset;
                                        for (int i = first_piece_index + 1; i <= last_piece_index; i++) {
                                            DiskManagerPiece piece = pieces[i];
                                            if (piece.isDone()) {
                                                contiguous_downloaded += piece.getLength();
                                            } else {
                                                boolean[] blocks = piece.getWritten();
                                                if (blocks == null) {
                                                    if (piece.isDone()) {
                                                        contiguous_downloaded += piece.getLength();
                                                    } else {
                                                        break;
                                                    }
                                                } else {
                                                    for (int j = 0; j < blocks.length; j++) {
                                                        if (blocks[j]) {
                                                            contiguous_downloaded += piece.getBlockSize(j);
                                                        } else {
                                                            break;
                                                        }
                                                    }
                                                }
                                                break;
                                            }
                                        }
                                    }
                                } catch (Throwable e) {
                                // Debug.out( e );
                                }
                                if (contiguous_downloaded < file_size) {
                                    // things might have improved, check again
                                    current_downloaded = job.getFile().getDownloaded();
                                    if (current_downloaded < file_size) {
                                        Debug.out("Premature transcode termination: init=" + initial_file_downloaded + ", curr=" + current_downloaded + ", len=" + file_size);
                                        error[0] = new TranscodeException("Transcode terminated prematurely");
                                    }
                                }
                            }
                        }
                    } finally {
                        xcode_sem.release();
                    }
                }
            };
            boolean direct_input = job.useDirectInput();
            if (job.isStream()) {
                /*
					provider_job[0] =
						provider.transcode(
							adapter,
							job.getFile(),
							profile,
							new File( "C:\\temp\\arse").toURI().toURL());
					*/
                pipe = new TranscodePipeStreamSource2(new TranscodePipeStreamSource2.streamListener() {

                    @Override
                    public void gotStream(InputStream is) {
                        job.setStream(is);
                    }
                });
                provider_job[0] = provider.transcode(xcode_adapter, provider_analysis, direct_input, job.getFile(), profile, new URL("tcp://127.0.0.1:" + pipe.getPort()));
            } else {
                File output_file = transcode_file.getCacheFile();
                provider_job[0] = provider.transcode(xcode_adapter, provider_analysis, direct_input, job.getFile(), profile, output_file.toURI().toURL());
            }
            provider_job[0].setMaxBytesPerSecond(max_bytes_per_sec);
            TranscodeQueueListener listener = new TranscodeQueueListener() {

                @Override
                public void jobAdded(TranscodeJob job) {
                }

                @Override
                public void jobChanged(TranscodeJob changed_job) {
                    if (changed_job == job) {
                        int state = job.getState();
                        if (state == TranscodeJob.ST_PAUSED) {
                            provider_job[0].pause();
                        } else if (state == TranscodeJob.ST_RUNNING) {
                            provider_job[0].resume();
                        } else if (state == TranscodeJob.ST_CANCELLED || state == TranscodeJob.ST_STOPPED) {
                            provider_job[0].cancel();
                        }
                    }
                }

                @Override
                public void jobRemoved(TranscodeJob removed_job) {
                    if (removed_job == job) {
                        provider_job[0].cancel();
                    }
                }
            };
            try {
                addListener(listener);
                xcode_sem.reserve();
            } finally {
                removeListener(listener);
            }
            if (error[0] != null) {
                throw (error[0]);
            }
        } else {
            // no transcode required...
            DiskManagerFileInfo source = job.getFile();
            transcode_file.setTranscodeRequired(false);
            if (job.isStream()) {
                PluginInterface av_pi = PluginInitializer.getDefaultInterface().getPluginManager().getPluginInterfaceByID("azupnpav");
                if (av_pi == null) {
                    throw (new TranscodeException("Media Server plugin not found"));
                }
                IPCInterface av_ipc = av_pi.getIPC();
                String url_str = (String) av_ipc.invoke("getContentURL", new Object[] { source });
                if (url_str == null || url_str.length() == 0) {
                    // see if we can use the file directly
                    File source_file = source.getFile();
                    if (source_file.exists()) {
                        job.setStream(new BufferedInputStream(new FileInputStream(source_file)));
                    } else {
                        throw (new TranscodeException("No UPnPAV URL and file doesn't exist"));
                    }
                } else {
                    URL source_url = new URL(url_str);
                    job.setStream(source_url.openConnection().getInputStream());
                }
            } else {
                boolean url_input_source = source instanceof DiskManagerFileInfoURL;
                if (device.getAlwaysCacheFiles() || url_input_source) {
                    PluginInterface av_pi = PluginInitializer.getDefaultInterface().getPluginManager().getPluginInterfaceByID("azupnpav");
                    if (av_pi == null) {
                        throw (new TranscodeException("Media Server plugin not found"));
                    }
                    IPCInterface av_ipc = av_pi.getIPC();
                    String url_str = (String) av_ipc.invoke("getContentURL", new Object[] { source });
                    InputStream is;
                    long length;
                    if (url_str == null || url_str.length() == 0) {
                        if (url_input_source) {
                            ((DiskManagerFileInfoURL) source).download();
                        }
                        File source_file = source.getFile();
                        if (source_file.exists()) {
                            is = new BufferedInputStream(new FileInputStream(source_file));
                            length = source_file.length();
                        } else {
                            throw (new TranscodeException("No UPnPAV URL and file doesn't exist"));
                        }
                    } else {
                        URL source_url = new URL(url_str);
                        URLConnection connection = source_url.openConnection();
                        is = source_url.openConnection().getInputStream();
                        String s = connection.getHeaderField("content-length");
                        if (s != null) {
                            length = Long.parseLong(s);
                        } else {
                            length = -1;
                        }
                    }
                    OutputStream os = null;
                    final boolean[] cancel_copy = { false };
                    TranscodeQueueListener copy_listener = new TranscodeQueueListener() {

                        @Override
                        public void jobAdded(TranscodeJob job) {
                        }

                        @Override
                        public void jobChanged(TranscodeJob changed_job) {
                            if (changed_job == job) {
                                int state = job.getState();
                                if (state == TranscodeJob.ST_PAUSED) {
                                } else if (state == TranscodeJob.ST_RUNNING) {
                                } else if (state == TranscodeJob.ST_CANCELLED || state == TranscodeJob.ST_STOPPED) {
                                    cancel_copy[0] = true;
                                }
                            }
                        }

                        @Override
                        public void jobRemoved(TranscodeJob removed_job) {
                            if (removed_job == job) {
                                cancel_copy[0] = true;
                            }
                        }
                    };
                    try {
                        addListener(copy_listener);
                        os = new FileOutputStream(transcode_file.getCacheFile());
                        long total_copied = 0;
                        byte[] buffer = new byte[128 * 1024];
                        while (true) {
                            if (cancel_copy[0]) {
                                throw (new TranscodeException("Copy cancelled"));
                            }
                            int len = is.read(buffer);
                            if (len <= 0) {
                                break;
                            }
                            os.write(buffer, 0, len);
                            total_copied += len;
                            if (length > 0) {
                                job.updateProgress((int) (total_copied * 100 / length), -1);
                            }
                            total_copied += len;
                        }
                    } finally {
                        try {
                            is.close();
                        } catch (Throwable e) {
                            Debug.out(e);
                        }
                        try {
                            if (os != null) {
                                os.close();
                            }
                        } catch (Throwable e) {
                            Debug.out(e);
                        }
                        removeListener(copy_listener);
                    }
                }
            }
        }
        job.complete();
        return (true);
    } catch (Throwable e) {
        job.failed(e);
        e.printStackTrace();
        if (!job.isStream() && job.getEnableAutoRetry() && job.getAutoRetryCount() == 0 && job.canUseDirectInput() && !job.useDirectInput()) {
            log("Auto-retrying transcode with direct input");
            job.setUseDirectInput();
            job.setAutoRetry(true);
            queue_sem.release();
        }
        return (false);
    } finally {
        if (pipe != null) {
            pipe.destroy();
        }
        device.setTranscoding(false);
        current_job = null;
    }
}
Also used : DiskManager(com.biglybt.pif.disk.DiskManager) TOTorrentFile(com.biglybt.core.torrent.TOTorrentFile) DiskManagerFileInfoURL(com.biglybt.core.download.DiskManagerFileInfoURL) TOTorrentFile(com.biglybt.core.torrent.TOTorrentFile) DiskManagerFileInfoURL(com.biglybt.core.download.DiskManagerFileInfoURL) URL(java.net.URL) DiskManagerPiece(com.biglybt.core.disk.DiskManagerPiece) Download(com.biglybt.pif.download.Download) IPCInterface(com.biglybt.pif.ipc.IPCInterface) DiskManagerFileInfo(com.biglybt.pif.disk.DiskManagerFileInfo) PluginInterface(com.biglybt.pif.PluginInterface) Average(com.biglybt.core.util.average.Average) URLConnection(java.net.URLConnection) TOTorrent(com.biglybt.core.torrent.TOTorrent)

Example 2 with DiskManagerFileInfoURL

use of com.biglybt.core.download.DiskManagerFileInfoURL in project BiglyBT by BiglySoftware.

the class TranscodeProviderVuze method transcode.

@Override
public TranscodeProviderJob transcode(final TranscodeProviderAdapter _adapter, TranscodeProviderAnalysis analysis, boolean direct_input, DiskManagerFileInfo input, TranscodeProfile profile, URL output) throws TranscodeException {
    try {
        PluginInterface av_pi = plugin_interface.getPluginManager().getPluginInterfaceByID("azupnpav");
        if (av_pi == null) {
            throw (new TranscodeException("Media Server plugin not found"));
        }
        final TranscodeProviderJob[] xcode_job = { null };
        URL source_url = null;
        TranscodePipe pipe = null;
        if (direct_input) {
            if (input instanceof DiskManagerFileInfoURL) {
                ((DiskManagerFileInfoURL) input).download();
            }
            if (input.getDownloaded() == input.getLength()) {
                File file = input.getFile();
                if (file.exists() && file.length() == input.getLength()) {
                    source_url = file.toURI().toURL();
                }
            }
            if (source_url == null) {
                manager.log("Failed to use direct input as source file doesn't exist/incomplete");
            }
        }
        if (source_url == null) {
            if (input instanceof DiskManagerFileInfoURL) {
                source_url = ((DiskManagerFileInfoURL) input).getURL();
            } else {
                IPCInterface av_ipc = av_pi.getIPC();
                String url_str = (String) av_ipc.invoke("getContentURL", new Object[] { input });
                if (url_str == null || url_str.length() == 0) {
                    // see if we can use the file directly
                    File source_file = input.getFile();
                    if (source_file.exists()) {
                        pipe = new TranscodePipeFileSource(source_file, new TranscodePipe.errorListener() {

                            @Override
                            public void error(Throwable e) {
                                _adapter.failed(new TranscodeException("File access error", e));
                                if (xcode_job[0] != null) {
                                    xcode_job[0].cancel();
                                }
                            }
                        });
                        source_url = new URL("http://127.0.0.1:" + pipe.getPort() + "/");
                    } else {
                        throw (new TranscodeException("Source file doesn't exist"));
                    }
                } else {
                    source_url = new URL(url_str);
                    pipe = new TranscodePipeStreamSource(source_url.getHost(), source_url.getPort());
                    source_url = UrlUtils.setHost(source_url, "127.0.0.1");
                    source_url = UrlUtils.setPort(source_url, pipe.getPort());
                }
            }
        }
        final TranscodePipe f_pipe = pipe;
        try {
            final IPCInterface ipc = plugin_interface.getIPC();
            final Object context;
            final TranscodeProviderAdapter adapter;
            if (output.getProtocol().equals("tcp")) {
                adapter = _adapter;
                context = ipc.invoke("transcodeToTCP", new Object[] { ((TranscodeProviderAnalysisImpl) analysis).getResult(), source_url, profile.getName(), output.getPort() });
            } else {
                final File file = new File(output.toURI());
                File parent_dir = file.getParentFile();
                if (parent_dir.exists()) {
                    if (!parent_dir.canWrite()) {
                        throw (new TranscodeException("Folder '" + parent_dir.getAbsolutePath() + "' isn't writable"));
                    }
                } else {
                    if (!parent_dir.mkdirs()) {
                        throw (new TranscodeException("Failed to create folder '" + parent_dir.getAbsolutePath() + "'"));
                    }
                }
                adapter = new TranscodeProviderAdapter() {

                    @Override
                    public void updateProgress(int percent, int eta_secs, int width, int height) {
                        _adapter.updateProgress(percent, eta_secs, width, height);
                    }

                    @Override
                    public void streamStats(long connect_rate, long write_speed) {
                        _adapter.streamStats(connect_rate, write_speed);
                    }

                    @Override
                    public void failed(TranscodeException error) {
                        try {
                            file.delete();
                        } finally {
                            _adapter.failed(error);
                        }
                    }

                    @Override
                    public void complete() {
                        _adapter.complete();
                    }
                };
                context = ipc.invoke("transcodeToFile", new Object[] { ((TranscodeProviderAnalysisImpl) analysis).getResult(), source_url, profile.getName(), file });
            }
            new AEThread2("xcodeStatus", true) {

                @Override
                public void run() {
                    try {
                        boolean in_progress = true;
                        while (in_progress) {
                            in_progress = false;
                            if (f_pipe != null) {
                                adapter.streamStats(f_pipe.getConnectionRate(), f_pipe.getWriteSpeed());
                            }
                            try {
                                Map status = (Map) ipc.invoke("getTranscodeStatus", new Object[] { context });
                                long state = (Long) status.get("state");
                                if (state == 0) {
                                    int percent = (Integer) status.get("percent");
                                    Integer i_eta = (Integer) status.get("eta_secs");
                                    int eta = i_eta == null ? -1 : i_eta;
                                    Integer i_width = (Integer) status.get("new_width");
                                    int width = i_width == null ? 0 : i_width;
                                    Integer i_height = (Integer) status.get("new_height");
                                    int height = i_height == null ? 0 : i_height;
                                    adapter.updateProgress(percent, eta, width, height);
                                    if (percent == 100) {
                                        adapter.complete();
                                    } else {
                                        in_progress = true;
                                        Thread.sleep(1000);
                                    }
                                } else if (state == 1) {
                                    adapter.failed(new TranscodeException("Transcode cancelled"));
                                } else {
                                    Boolean perm_fail = (Boolean) status.get("error_is_perm");
                                    TranscodeException error = new TranscodeException("Transcode failed", (Throwable) status.get("error"));
                                    if (perm_fail != null && perm_fail) {
                                        error.setDisableRetry(true);
                                    }
                                    adapter.failed(error);
                                }
                            } catch (Throwable e) {
                                adapter.failed(new TranscodeException("Failed to get status", e));
                            }
                        }
                    } finally {
                        if (f_pipe != null) {
                            f_pipe.destroy();
                        }
                    }
                }
            }.start();
            xcode_job[0] = new TranscodeProviderJob() {

                @Override
                public void pause() {
                    if (f_pipe != null) {
                        f_pipe.pause();
                    }
                }

                @Override
                public void resume() {
                    if (f_pipe != null) {
                        f_pipe.resume();
                    }
                }

                @Override
                public void cancel() {
                    try {
                        ipc.invoke("cancelTranscode", new Object[] { context });
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }

                @Override
                public void setMaxBytesPerSecond(int max) {
                    if (f_pipe != null) {
                        f_pipe.setMaxBytesPerSecond(max);
                    }
                }
            };
            return (xcode_job[0]);
        } catch (Throwable e) {
            if (pipe != null) {
                pipe.destroy();
            }
            throw (e);
        }
    } catch (TranscodeException e) {
        throw (e);
    } catch (Throwable e) {
        throw (new TranscodeException("transcode failed", e));
    }
}
Also used : PluginInterface(com.biglybt.pif.PluginInterface) DiskManagerFileInfoURL(com.biglybt.core.download.DiskManagerFileInfoURL) URL(java.net.URL) AEThread2(com.biglybt.core.util.AEThread2) DiskManagerFileInfoURL(com.biglybt.core.download.DiskManagerFileInfoURL) File(java.io.File) IPCInterface(com.biglybt.pif.ipc.IPCInterface) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with DiskManagerFileInfoURL

use of com.biglybt.core.download.DiskManagerFileInfoURL in project BiglyBT by BiglySoftware.

the class TranscodeProviderVuze method analyse.

@Override
public TranscodeProviderAnalysis analyse(final TranscodeProviderAdapter _adapter, DiskManagerFileInfo input, TranscodeProfile profile) throws TranscodeException {
    try {
        URL source_url = null;
        File source_file = null;
        long input_length = input.getLength();
        if (input_length > 0 && input_length == input.getDownloaded()) {
            File file = input.getFile();
            if (file.exists() && file.length() == input_length) {
                source_file = file;
            }
        }
        TranscodePipe pipe = null;
        if (source_file == null) {
            if (input instanceof DiskManagerFileInfoURL) {
                source_url = ((DiskManagerFileInfoURL) input).getURL();
            } else {
                for (int i = 0; i < 10; i++) {
                    PluginInterface av_pi = plugin_interface.getPluginManager().getPluginInterfaceByID("azupnpav");
                    if (av_pi == null) {
                        throw (new TranscodeException("Media Server plugin not found"));
                    }
                    IPCInterface av_ipc = av_pi.getIPC();
                    String url_str = (String) av_ipc.invoke("getContentURL", new Object[] { input });
                    if (url_str != null && url_str.length() > 0) {
                        source_url = new URL(url_str);
                        pipe = new TranscodePipeStreamSource(source_url.getHost(), source_url.getPort());
                        source_url = UrlUtils.setHost(source_url, "127.0.0.1");
                        source_url = UrlUtils.setPort(source_url, pipe.getPort());
                    }
                    if (source_url != null) {
                        break;
                    } else {
                        try {
                            Thread.sleep(1000);
                        } catch (Throwable e) {
                            break;
                        }
                    }
                }
            }
        }
        if (source_file == null && source_url == null) {
            throw (new TranscodeException("File doesn't exist"));
        }
        final TranscodePipe f_pipe = pipe;
        try {
            final IPCInterface ipc = plugin_interface.getIPC();
            final Object analysis_context;
            if (source_url != null) {
                analysis_context = ipc.invoke("analyseContent", new Object[] { source_url, profile.getName() });
            } else {
                analysis_context = ipc.invoke("analyseContent", new Object[] { source_file, profile.getName() });
            }
            final Map<String, Object> result = new HashMap<>();
            final TranscodeProviderAnalysisImpl analysis = new TranscodeProviderAnalysisImpl() {

                @Override
                public void cancel() {
                    try {
                        ipc.invoke("cancelAnalysis", new Object[] { analysis_context });
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }

                @Override
                public boolean foundVideoStream() {
                    return (getLongProperty(PT_VIDEO_WIDTH) > 0);
                }

                @Override
                public boolean getBooleanProperty(int property) {
                    if (property == PT_TRANSCODE_REQUIRED) {
                        return (getBooleanProperty("xcode_required", true));
                    } else {
                        Debug.out("Unknown property: " + property);
                        return (false);
                    }
                }

                @Override
                public void setBooleanProperty(int property, boolean value) {
                    if (property == PT_FORCE_TRANSCODE) {
                        result.put("force_xcode", value);
                    } else {
                        Debug.out("Unknown property: " + property);
                    }
                }

                @Override
                public long getLongProperty(int property) {
                    if (property == PT_DURATION_MILLIS) {
                        long duration = getLongProperty("duration_millis", 0);
                        long audio_duration = getLongProperty("audio_duration_millis", 0);
                        if (duration <= 0 && audio_duration > 0) {
                            duration = audio_duration;
                        }
                        if (audio_duration > 0 && audio_duration < duration) {
                            duration = audio_duration;
                        }
                        return (duration);
                    } else if (property == PT_VIDEO_WIDTH) {
                        return (getLongProperty("video_width", 0));
                    } else if (property == PT_VIDEO_HEIGHT) {
                        return (getLongProperty("video_height", 0));
                    } else if (property == PT_SOURCE_SIZE) {
                        return (getLongProperty("source_size", 0));
                    } else if (property == PT_ESTIMATED_XCODE_SIZE) {
                        return (getLongProperty("estimated_transcoded_size", 0));
                    } else {
                        Debug.out("Unknown property: " + property);
                        return (0);
                    }
                }

                protected boolean getBooleanProperty(String name, boolean def) {
                    Boolean b = (Boolean) result.get(name);
                    if (b != null) {
                        return (b);
                    }
                    return (def);
                }

                protected long getLongProperty(String name, long def) {
                    Long l = (Long) result.get(name);
                    if (l != null) {
                        return (l);
                    }
                    return (def);
                }

                @Override
                public Map<String, Object> getResult() {
                    return (result);
                }
            };
            new AEThread2("analysisStatus", true) {

                @Override
                public void run() {
                    try {
                        while (true) {
                            try {
                                Map status = (Map) ipc.invoke("getAnalysisStatus", new Object[] { analysis_context });
                                long state = (Long) status.get("state");
                                if (state == 0) {
                                    // running
                                    Thread.sleep(50);
                                } else if (state == 1) {
                                    _adapter.failed(new TranscodeException("Analysis cancelled"));
                                    break;
                                } else if (state == 2) {
                                    _adapter.failed(new TranscodeException("Analysis failed", (Throwable) status.get("error")));
                                    break;
                                } else {
                                    result.putAll((Map<String, Object>) status.get("result"));
                                    _adapter.complete();
                                    break;
                                }
                            } catch (Throwable e) {
                                _adapter.failed(new TranscodeException("Failed to get status", e));
                                break;
                            }
                        }
                    } finally {
                        if (f_pipe != null) {
                            f_pipe.destroy();
                        }
                    }
                }
            }.start();
            return (analysis);
        } catch (Throwable e) {
            if (pipe != null) {
                pipe.destroy();
            }
            throw (e);
        }
    } catch (TranscodeException e) {
        throw (e);
    } catch (Throwable e) {
        throw (new TranscodeException("analysis failed", e));
    }
}
Also used : HashMap(java.util.HashMap) PluginInterface(com.biglybt.pif.PluginInterface) DiskManagerFileInfoURL(com.biglybt.core.download.DiskManagerFileInfoURL) URL(java.net.URL) AEThread2(com.biglybt.core.util.AEThread2) DiskManagerFileInfoURL(com.biglybt.core.download.DiskManagerFileInfoURL) File(java.io.File) IPCInterface(com.biglybt.pif.ipc.IPCInterface) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

DiskManagerFileInfoURL (com.biglybt.core.download.DiskManagerFileInfoURL)3 PluginInterface (com.biglybt.pif.PluginInterface)3 IPCInterface (com.biglybt.pif.ipc.IPCInterface)3 URL (java.net.URL)3 AEThread2 (com.biglybt.core.util.AEThread2)2 File (java.io.File)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 DiskManagerPiece (com.biglybt.core.disk.DiskManagerPiece)1 TOTorrent (com.biglybt.core.torrent.TOTorrent)1 TOTorrentFile (com.biglybt.core.torrent.TOTorrentFile)1 Average (com.biglybt.core.util.average.Average)1 DiskManager (com.biglybt.pif.disk.DiskManager)1 DiskManagerFileInfo (com.biglybt.pif.disk.DiskManagerFileInfo)1 Download (com.biglybt.pif.download.Download)1 URLConnection (java.net.URLConnection)1