Recherche avancée

Médias (91)

Autres articles (82)

  • MediaSPIP v0.2

    21 juin 2013, par

    MediaSPIP 0.2 est la première version de MediaSPIP stable.
    Sa date de sortie officielle est le 21 juin 2013 et est annoncée ici.
    Le fichier zip ici présent contient uniquement les sources de MediaSPIP en version standalone.
    Comme pour la version précédente, il est nécessaire d’installer manuellement l’ensemble des dépendances logicielles sur le serveur.
    Si vous souhaitez utiliser cette archive pour une installation en mode ferme, il vous faudra également procéder à d’autres modifications (...)

  • Mise à disposition des fichiers

    14 avril 2011, par

    Par défaut, lors de son initialisation, MediaSPIP ne permet pas aux visiteurs de télécharger les fichiers qu’ils soient originaux ou le résultat de leur transformation ou encodage. Il permet uniquement de les visualiser.
    Cependant, il est possible et facile d’autoriser les visiteurs à avoir accès à ces documents et ce sous différentes formes.
    Tout cela se passe dans la page de configuration du squelette. Il vous faut aller dans l’espace d’administration du canal, et choisir dans la navigation (...)

  • MediaSPIP version 0.1 Beta

    16 avril 2011, par

    MediaSPIP 0.1 beta est la première version de MediaSPIP décrétée comme "utilisable".
    Le fichier zip ici présent contient uniquement les sources de MediaSPIP en version standalone.
    Pour avoir une installation fonctionnelle, il est nécessaire d’installer manuellement l’ensemble des dépendances logicielles sur le serveur.
    Si vous souhaitez utiliser cette archive pour une installation en mode ferme, il vous faudra également procéder à d’autres modifications (...)

Sur d’autres sites (6066)

  • exo player mp2, aac audio format and avi video format [closed]

    27 mai 2020, par Muhammet
    

    

    /*&#xD;&#xA; * Copyright (C) 2016 The Android Open Source Project&#xD;&#xA; *&#xD;&#xA; * Licensed under the Apache License, Version 2.0 (the "License");&#xD;&#xA; * you may not use this file except in compliance with the License.&#xD;&#xA; * You may obtain a copy of the License at&#xD;&#xA; *&#xD;&#xA; *      http://www.apache.org/licenses/LICENSE-2.0&#xD;&#xA; *&#xD;&#xA; * Unless required by applicable law or agreed to in writing, software&#xD;&#xA; * distributed under the License is distributed on an "AS IS" BASIS,&#xD;&#xA; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#xD;&#xA; * See the License for the specific language governing permissions and&#xD;&#xA; * limitations under the License.&#xD;&#xA; */&#xD;&#xA;package com.google.android.exoplayer2.ext.ffmpeg;&#xD;&#xA;&#xD;&#xA;import android.os.Handler;&#xD;&#xA;import androidx.annotation.Nullable;&#xD;&#xA;import com.google.android.exoplayer2.C;&#xD;&#xA;import com.google.android.exoplayer2.ExoPlaybackException;&#xD;&#xA;import com.google.android.exoplayer2.Format;&#xD;&#xA;import com.google.android.exoplayer2.audio.AudioProcessor;&#xD;&#xA;import com.google.android.exoplayer2.audio.AudioRendererEventListener;&#xD;&#xA;import com.google.android.exoplayer2.audio.AudioSink;&#xD;&#xA;import com.google.android.exoplayer2.audio.DefaultAudioSink;&#xD;&#xA;import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer;&#xD;&#xA;import com.google.android.exoplayer2.drm.DrmSessionManager;&#xD;&#xA;import com.google.android.exoplayer2.drm.ExoMediaCrypto;&#xD;&#xA;import com.google.android.exoplayer2.util.Assertions;&#xD;&#xA;import com.google.android.exoplayer2.util.MimeTypes;&#xD;&#xA;import java.util.Collections;&#xD;&#xA;import org.checkerframework.checker.nullness.qual.MonotonicNonNull;&#xD;&#xA;&#xD;&#xA;/**&#xD;&#xA; * Decodes and renders audio using FFmpeg.&#xD;&#xA; */&#xD;&#xA;public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer {&#xD;&#xA;&#xD;&#xA;  /** The number of input and output buffers. */&#xD;&#xA;  private static final int NUM_BUFFERS = 16;&#xD;&#xA;  /** The default input buffer size. */&#xD;&#xA;  private static final int DEFAULT_INPUT_BUFFER_SIZE = 960 * 6;&#xD;&#xA;&#xD;&#xA;  private final boolean enableFloatOutput;&#xD;&#xA;&#xD;&#xA;  private @MonotonicNonNull FfmpegDecoder decoder;&#xD;&#xA;&#xD;&#xA;  public FfmpegAudioRenderer() {&#xD;&#xA;    this(/* eventHandler= */ null, /* eventListener= */ null);&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  /**&#xD;&#xA;   * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be&#xD;&#xA;   *     null if delivery of events is not required.&#xD;&#xA;   * @param eventListener A listener of events. May be null if delivery of events is not required.&#xD;&#xA;   * @param audioProcessors Optional {@link AudioProcessor}s that will process audio before output.&#xD;&#xA;   */&#xD;&#xA;  public FfmpegAudioRenderer(&#xD;&#xA;          @Nullable Handler eventHandler,&#xD;&#xA;          @Nullable AudioRendererEventListener eventListener,&#xD;&#xA;          AudioProcessor... audioProcessors) {&#xD;&#xA;    this(&#xD;&#xA;            eventHandler,&#xD;&#xA;            eventListener,&#xD;&#xA;            new DefaultAudioSink(/* audioCapabilities= */ null, audioProcessors),&#xD;&#xA;            /* enableFloatOutput= */ false);&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  /**&#xD;&#xA;   * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be&#xD;&#xA;   *     null if delivery of events is not required.&#xD;&#xA;   * @param eventListener A listener of events. May be null if delivery of events is not required.&#xD;&#xA;   * @param audioSink The sink to which audio will be output.&#xD;&#xA;   * @param enableFloatOutput Whether to enable 32-bit float audio format, if supported on the&#xD;&#xA;   *     device/build and if the input format may have bit depth higher than 16-bit. When using&#xD;&#xA;   *     32-bit float output, any audio processing will be disabled, including playback speed/pitch&#xD;&#xA;   *     adjustment.&#xD;&#xA;   */&#xD;&#xA;  public FfmpegAudioRenderer(&#xD;&#xA;          @Nullable Handler eventHandler,&#xD;&#xA;          @Nullable AudioRendererEventListener eventListener,&#xD;&#xA;          AudioSink audioSink,&#xD;&#xA;          boolean enableFloatOutput) {&#xD;&#xA;    super(&#xD;&#xA;            eventHandler,&#xD;&#xA;            eventListener,&#xD;&#xA;            /* drmSessionManager= */ null,&#xD;&#xA;            /* playClearSamplesWithoutKeys= */ false,&#xD;&#xA;            audioSink);&#xD;&#xA;    this.enableFloatOutput = enableFloatOutput;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  @Override&#xD;&#xA;  @FormatSupport&#xD;&#xA;  protected int supportsFormatInternal(&#xD;&#xA;          @Nullable DrmSessionManager<exomediacrypto> drmSessionManager, Format format) {&#xD;&#xA;    Assertions.checkNotNull(format.sampleMimeType);&#xD;&#xA;    if (!FfmpegLibrary.isAvailable()) {&#xD;&#xA;      return FORMAT_UNSUPPORTED_TYPE;&#xD;&#xA;    } else if (!FfmpegLibrary.supportsFormat(format.sampleMimeType) || !isOutputSupported(format)) {&#xD;&#xA;      return FORMAT_UNSUPPORTED_SUBTYPE;&#xD;&#xA;    } else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {&#xD;&#xA;      return FORMAT_UNSUPPORTED_DRM;&#xD;&#xA;    } else {&#xD;&#xA;      return FORMAT_HANDLED;&#xD;&#xA;    }&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  @Override&#xD;&#xA;  @AdaptiveSupport&#xD;&#xA;  public final int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException {&#xD;&#xA;    return ADAPTIVE_NOT_SEAMLESS;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  @Override&#xD;&#xA;  protected FfmpegDecoder createDecoder(Format format, @Nullable ExoMediaCrypto mediaCrypto)&#xD;&#xA;          throws FfmpegDecoderException {&#xD;&#xA;    int initialInputBufferSize =&#xD;&#xA;            format.maxInputSize != Format.NO_VALUE ? format.maxInputSize : DEFAULT_INPUT_BUFFER_SIZE;&#xD;&#xA;    decoder =&#xD;&#xA;            new FfmpegDecoder(&#xD;&#xA;                    NUM_BUFFERS, NUM_BUFFERS, initialInputBufferSize, format, shouldUseFloatOutput(format));&#xD;&#xA;    return decoder;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  @Override&#xD;&#xA;  public Format getOutputFormat() {&#xD;&#xA;    Assertions.checkNotNull(decoder);&#xD;&#xA;    int channelCount = decoder.getChannelCount();&#xD;&#xA;    int sampleRate = decoder.getSampleRate();&#xD;&#xA;    @C.PcmEncoding int encoding = decoder.getEncoding();&#xD;&#xA;    return Format.createAudioSampleFormat(&#xD;&#xA;            /* id= */ null,&#xD;&#xA;            MimeTypes.AUDIO_RAW,&#xD;&#xA;            /* codecs= */ null,&#xD;&#xA;            Format.NO_VALUE,&#xD;&#xA;            Format.NO_VALUE,&#xD;&#xA;            channelCount,&#xD;&#xA;            sampleRate,&#xD;&#xA;            encoding,&#xD;&#xA;            Collections.emptyList(),&#xD;&#xA;            /* drmInitData= */ null,&#xD;&#xA;            /* selectionFlags= */ 0,&#xD;&#xA;            /* language= */ null);&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  private boolean isOutputSupported(Format inputFormat) {&#xD;&#xA;    return shouldUseFloatOutput(inputFormat)&#xD;&#xA;            || supportsOutput(inputFormat.channelCount, C.ENCODING_PCM_16BIT);&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  private boolean shouldUseFloatOutput(Format inputFormat) {&#xD;&#xA;    Assertions.checkNotNull(inputFormat.sampleMimeType);&#xD;&#xA;    if (!enableFloatOutput || !supportsOutput(inputFormat.channelCount, C.ENCODING_PCM_FLOAT)) {&#xD;&#xA;      return false;&#xD;&#xA;    }&#xD;&#xA;    switch (inputFormat.sampleMimeType) {&#xD;&#xA;      case MimeTypes.AUDIO_RAW:&#xD;&#xA;        // For raw audio, output in 32-bit float encoding if the bit depth is > 16-bit.&#xD;&#xA;        return inputFormat.pcmEncoding == C.ENCODING_PCM_24BIT&#xD;&#xA;                || inputFormat.pcmEncoding == C.ENCODING_PCM_32BIT&#xD;&#xA;                || inputFormat.pcmEncoding == C.ENCODING_PCM_FLOAT;&#xD;&#xA;      case MimeTypes.AUDIO_AC3:&#xD;&#xA;        // AC-3 is always 16-bit, so there is no point outputting in 32-bit float encoding.&#xD;&#xA;        return false;&#xD;&#xA;      default:&#xD;&#xA;        // For all other formats, assume that it&#x27;s worth using 32-bit float encoding.&#xD;&#xA;        return true;&#xD;&#xA;    }&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;}</exomediacrypto>

    &#xD;&#xA;

    &#xD;&#xA;

    &#xD;&#xA;&#xA;&#xA;

    I use exoplayer but no sound from mp2 and aac audio formats in android application.

    &#xA;&#xA;

    I get this error when I open mp2 and aac audio format videos "media includes audio tracks but none

    &#xA;&#xA;

    are playable by this device"and some are not working in .avi format, some are working please can you help me

    &#xA;&#xA;

    &#xD;&#xA;
    &#xD;&#xA;
    /*&#xD;&#xA; * Copyright (C) 2016 The Android Open Source Project&#xD;&#xA; *&#xD;&#xA; * Licensed under the Apache License, Version 2.0 (the "License");&#xD;&#xA; * you may not use this file except in compliance with the License.&#xD;&#xA; * You may obtain a copy of the License at&#xD;&#xA; *&#xD;&#xA; *      http://www.apache.org/licenses/LICENSE-2.0&#xD;&#xA; *&#xD;&#xA; * Unless required by applicable law or agreed to in writing, software&#xD;&#xA; * distributed under the License is distributed on an "AS IS" BASIS,&#xD;&#xA; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#xD;&#xA; * See the License for the specific language governing permissions and&#xD;&#xA; * limitations under the License.&#xD;&#xA; */&#xD;&#xA;package com.google.android.exoplayer2.ext.ffmpeg;&#xD;&#xA;&#xD;&#xA;import androidx.annotation.Nullable;&#xD;&#xA;import com.google.android.exoplayer2.ExoPlayerLibraryInfo;&#xD;&#xA;import com.google.android.exoplayer2.util.LibraryLoader;&#xD;&#xA;import com.google.android.exoplayer2.util.Log;&#xD;&#xA;import com.google.android.exoplayer2.util.MimeTypes;&#xD;&#xA;&#xD;&#xA;/**&#xD;&#xA; * Configures and queries the underlying native library.&#xD;&#xA; */&#xD;&#xA;public final class FfmpegLibrary {&#xD;&#xA;&#xD;&#xA;  static {&#xD;&#xA;    ExoPlayerLibraryInfo.registerModule("goog.exo.ffmpeg");&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  private static final String TAG = "FfmpegLibrary";&#xD;&#xA;&#xD;&#xA;  private static final LibraryLoader LOADER =&#xD;&#xA;          new LibraryLoader("avutil", "swresample", "avcodec", "ffmpeg");&#xD;&#xA;&#xD;&#xA;  private FfmpegLibrary() {}&#xD;&#xA;&#xD;&#xA;  /**&#xD;&#xA;   * Override the names of the FFmpeg native libraries. If an application wishes to call this&#xD;&#xA;   * method, it must do so before calling any other method defined by this class, and before&#xD;&#xA;   * instantiating a {@link FfmpegAudioRenderer} instance.&#xD;&#xA;   *&#xD;&#xA;   * @param libraries The names of the FFmpeg native libraries.&#xD;&#xA;   */&#xD;&#xA;  public static void setLibraries(String... libraries) {&#xD;&#xA;    LOADER.setLibraries(libraries);&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  /**&#xD;&#xA;   * Returns whether the underlying library is available, loading it if necessary.&#xD;&#xA;   */&#xD;&#xA;  public static boolean isAvailable() {&#xD;&#xA;    return LOADER.isAvailable();&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  /** Returns the version of the underlying library if available, or null otherwise. */&#xD;&#xA;  public static @Nullable String getVersion() {&#xD;&#xA;    return isAvailable() ? ffmpegGetVersion() : null;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  /**&#xD;&#xA;   * Returns whether the underlying library supports the specified MIME type.&#xD;&#xA;   *&#xD;&#xA;   * @param mimeType The MIME type to check.&#xD;&#xA;   */&#xD;&#xA;  public static boolean supportsFormat(String mimeType) {&#xD;&#xA;    if (!isAvailable()) {&#xD;&#xA;      return false;&#xD;&#xA;    }&#xD;&#xA;    String codecName = getCodecName(mimeType);&#xD;&#xA;    if (codecName == null) {&#xD;&#xA;      return false;&#xD;&#xA;    }&#xD;&#xA;    if (!ffmpegHasDecoder(codecName)) {&#xD;&#xA;      Log.w(TAG, "No " &#x2B; codecName &#x2B; " decoder available. Check the FFmpeg build configuration.");&#xD;&#xA;      return false;&#xD;&#xA;    }&#xD;&#xA;    return true;&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  /**&#xD;&#xA;   * Returns the name of the FFmpeg decoder that could be used to decode the format, or {@code null}&#xD;&#xA;   * if it&#x27;s unsupported.&#xD;&#xA;   */&#xD;&#xA;  /* package */ static @Nullable String getCodecName(String mimeType) {&#xD;&#xA;    switch (mimeType) {&#xD;&#xA;      case MimeTypes.AUDIO_AAC:&#xD;&#xA;        return "aac";&#xD;&#xA;      case MimeTypes.AUDIO_MPEG:&#xD;&#xA;      case MimeTypes.AUDIO_MPEG_L1:&#xD;&#xA;      case MimeTypes.AUDIO_MPEG_L2:&#xD;&#xA;        return "mp3";&#xD;&#xA;      case MimeTypes.AUDIO_AC3:&#xD;&#xA;        return "ac3";&#xD;&#xA;      case MimeTypes.AUDIO_E_AC3:&#xD;&#xA;      case MimeTypes.AUDIO_E_AC3_JOC:&#xD;&#xA;        return "eac3";&#xD;&#xA;      case MimeTypes.AUDIO_TRUEHD:&#xD;&#xA;        return "truehd";&#xD;&#xA;      case MimeTypes.AUDIO_DTS:&#xD;&#xA;      case MimeTypes.AUDIO_DTS_HD:&#xD;&#xA;        return "dca";&#xD;&#xA;      case MimeTypes.AUDIO_VORBIS:&#xD;&#xA;        return "vorbis";&#xD;&#xA;      case MimeTypes.AUDIO_OPUS:&#xD;&#xA;        return "opus";&#xD;&#xA;      case MimeTypes.AUDIO_AMR_NB:&#xD;&#xA;        return "amrnb";&#xD;&#xA;      case MimeTypes.AUDIO_AMR_WB:&#xD;&#xA;        return "amrwb";&#xD;&#xA;      case MimeTypes.AUDIO_FLAC:&#xD;&#xA;        return "flac";&#xD;&#xA;      case MimeTypes.AUDIO_ALAC:&#xD;&#xA;        return "alac";&#xD;&#xA;      case MimeTypes.AUDIO_MLAW:&#xD;&#xA;        return "pcm_mulaw";&#xD;&#xA;      case MimeTypes.AUDIO_ALAW:&#xD;&#xA;        return "pcm_alaw";&#xD;&#xA;      default:&#xD;&#xA;        return null;&#xD;&#xA;    }&#xD;&#xA;  }&#xD;&#xA;&#xD;&#xA;  private static native String ffmpegGetVersion();&#xD;&#xA;  private static native boolean ffmpegHasDecoder(String codecName);&#xD;&#xA;&#xD;&#xA;}

    &#xD;&#xA;

    &#xD;&#xA;

    &#xD;&#xA;&#xA;&#xA;

    [enter image description here][1]&#xA;[enter image description here][2]

    &#xA;

  • How to Stream Audio from Google Cloud Storage in Chunks and Convert Each Chunk to WAV for Whisper Transcription

    14 novembre 2024, par Douglas Landvik

    I'm working on a project where I need to transcribe audio stored in a Google Cloud Storage bucket using OpenAI's Whisper model. The audio is stored in WebM format with Opus encoding, and due to the file size, I'm streaming the audio in 30-second chunks.

    &#xA;

    To convert each chunk to WAV (16 kHz, mono, 16-bit PCM) compatible with Whisper, I'm using FFmpeg. The first chunk converts successfully, but subsequent chunks fail to convert. I suspect this is because each chunk lacks the WebM container's header, which FFmpeg needs to interpret the Opus codec correctly.

    &#xA;

    Here’s a simplified version of my approach :

    &#xA;

    Download Chunk : I download each chunk from GCS as bytes.&#xA;Convert with FFmpeg : I pass the bytes to FFmpeg to convert each chunk from WebM/Opus to WAV.

    &#xA;

    async def handle_transcription_and_notify(&#xA;    consultation_service: ConsultationService,&#xA;    consultation_processor: ConsultationProcessor,&#xA;    consultation: Consultation,&#xA;    language: str,&#xA;    notes: str,&#xA;    clinic_id: str,&#xA;    vet_email: str,&#xA;    trace_id: str,&#xA;    blob_path: str,&#xA;    max_retries: int = 3,&#xA;    retry_delay: int = 5,&#xA;    max_concurrent_tasks: int = 3&#xA;):&#xA;    """&#xA;    Handles the transcription process by streaming the file from GCS, converting to a compatible format, &#xA;    and notifying the client via WebSocket.&#xA;    """&#xA;    chunk_duration_sec = 30  # 30 seconds per chunk&#xA;    logger.info(f"Starting transcription process for consultation {consultation.consultation_id}",&#xA;                extra={&#x27;trace_id&#x27;: trace_id})&#xA;&#xA;    # Initialize GCS client&#xA;    service_account_key = os.environ.get(&#x27;SERVICE_ACCOUNT_KEY_BACKEND&#x27;)&#xA;    if not service_account_key:&#xA;        logger.error("Service account key not found in environment variables", extra={&#x27;trace_id&#x27;: trace_id})&#xA;        await send_discord_alert(&#xA;            f"Service account key not found for consultation {consultation.consultation_id}.\nTrace ID: {trace_id}"&#xA;        )&#xA;        return&#xA;&#xA;    try:&#xA;        service_account_info = json.loads(service_account_key)&#xA;        credentials = service_account.Credentials.from_service_account_info(service_account_info)&#xA;    except Exception as e:&#xA;        logger.error(f"Error loading service account credentials: {str(e)}", extra={&#x27;trace_id&#x27;: trace_id})&#xA;        await send_discord_alert(&#xA;            f"Error loading service account credentials for consultation {consultation.consultation_id}.\nError: {str(e)}\nTrace ID: {trace_id}"&#xA;        )&#xA;        return&#xA;&#xA;    # Initialize GCS client&#xA;    service_account_key = os.environ.get(&#x27;SERVICE_ACCOUNT_KEY_BACKEND&#x27;)&#xA;    if not service_account_key:&#xA;        logger.error("Service account key not found in environment variables", extra={&#x27;trace_id&#x27;: trace_id})&#xA;        await send_discord_alert(&#xA;            f"Service account key not found for consultation {consultation.consultation_id}.\nTrace ID: {trace_id}"&#xA;        )&#xA;        return&#xA;&#xA;    try:&#xA;        service_account_info = json.loads(service_account_key)&#xA;        credentials = service_account.Credentials.from_service_account_info(service_account_info)&#xA;    except Exception as e:&#xA;        logger.error(f"Error loading service account credentials: {str(e)}", extra={&#x27;trace_id&#x27;: trace_id})&#xA;        await send_discord_alert(&#xA;            f"Error loading service account credentials for consultation {consultation.consultation_id}.\nError: {str(e)}\nTrace ID: {trace_id}"&#xA;        )&#xA;        return&#xA;&#xA;    storage_client = storage.Client(credentials=credentials)&#xA;    bucket_name = &#x27;vetz_consultations&#x27;&#xA;    blob = storage_client.bucket(bucket_name).get_blob(blob_path)&#xA;    bytes_per_second = 16000 * 2  # 32,000 bytes per second&#xA;    chunk_size_bytes = 30 * bytes_per_second&#xA;    size = blob.size&#xA;&#xA;    async def stream_blob_in_chunks(blob, chunk_size):&#xA;        loop = asyncio.get_running_loop()&#xA;        start = 0&#xA;        size = blob.size&#xA;        while start &lt; size:&#xA;            end = min(start &#x2B; chunk_size - 1, size - 1)&#xA;            try:&#xA;                logger.info(f"Requesting chunk from {start} to {end}", extra={&#x27;trace_id&#x27;: trace_id})&#xA;                chunk = await loop.run_in_executor(&#xA;                    None, lambda: blob.download_as_bytes(start=start, end=end)&#xA;                )&#xA;                if not chunk:&#xA;                    break&#xA;                logger.info(f"Yielding chunk from {start} to {end}, size: {len(chunk)} bytes",&#xA;                            extra={&#x27;trace_id&#x27;: trace_id})&#xA;                yield chunk&#xA;                start &#x2B;= chunk_size&#xA;            except Exception as e:&#xA;                logger.error(f"Error downloading chunk from {start} to {end}: {str(e)}", exc_info=True,&#xA;                             extra={&#x27;trace_id&#x27;: trace_id})&#xA;                raise e&#xA;&#xA;    async def convert_to_wav(chunk_bytes, chunk_idx):&#xA;        """&#xA;        Convert audio chunk to WAV format compatible with Whisper, ensuring it&#x27;s 16 kHz, mono, and 16-bit PCM.&#xA;        """&#xA;        try:&#xA;            logger.debug(f"Processing chunk {chunk_idx}: size = {len(chunk_bytes)} bytes")&#xA;&#xA;            detected_format = await detect_audio_format(chunk_bytes)&#xA;            logger.info(f"Detected audio format for chunk {chunk_idx}: {detected_format}")&#xA;            input_io = io.BytesIO(chunk_bytes)&#xA;            output_io = io.BytesIO()&#xA;&#xA;            # ffmpeg command to convert webm/opus to WAV with 16 kHz, mono, and 16-bit PCM&#xA;&#xA;            # ffmpeg command with debug information&#xA;            ffmpeg_command = [&#xA;                "ffmpeg",&#xA;                "-loglevel", "debug",&#xA;                "-f", "s16le",            # Treat input as raw PCM data&#xA;                "-ar", "48000",           # Set input sample rate&#xA;                "-ac", "1",               # Set input to mono&#xA;                "-i", "pipe:0",&#xA;                "-ar", "16000",           # Set output sample rate to 16 kHz&#xA;                "-ac", "1",               # Ensure mono output&#xA;                "-sample_fmt", "s16",     # Set output format to 16-bit PCM&#xA;                "-f", "wav",              # Output as WAV format&#xA;                "pipe:1"&#xA;            ]&#xA;&#xA;            process = subprocess.Popen(&#xA;                ffmpeg_command,&#xA;                stdin=subprocess.PIPE,&#xA;                stdout=subprocess.PIPE,&#xA;                stderr=subprocess.PIPE&#xA;            )&#xA;&#xA;            stdout, stderr = process.communicate(input=input_io.read())&#xA;&#xA;            if process.returncode == 0:&#xA;                logger.info(f"FFmpeg conversion completed successfully for chunk {chunk_idx}")&#xA;                output_io.write(stdout)&#xA;                output_io.seek(0)&#xA;&#xA;                # Save the WAV file locally for listening&#xA;                output_dir = "converted_chunks"&#xA;                os.makedirs(output_dir, exist_ok=True)&#xA;                file_path = os.path.join(output_dir, f"chunk_{chunk_idx}.wav")&#xA;&#xA;                with open(file_path, "wb") as f:&#xA;                    f.write(stdout)&#xA;                logger.info(f"Chunk {chunk_idx} saved to {file_path}")&#xA;&#xA;                return output_io&#xA;            else:&#xA;                logger.error(f"FFmpeg failed for chunk {chunk_idx} with return code {process.returncode}")&#xA;                logger.error(f"Chunk {chunk_idx} - FFmpeg stderr: {stderr.decode()}")&#xA;                return None&#xA;&#xA;        except Exception as e:&#xA;            logger.error(f"Unexpected error in FFmpeg conversion for chunk {chunk_idx}: {str(e)}")&#xA;            return None&#xA;&#xA;    async def transcribe_chunk(idx, chunk_bytes):&#xA;        for attempt in range(1, max_retries &#x2B; 1):&#xA;            try:&#xA;                logger.info(f"Transcribing chunk {idx &#x2B; 1} (attempt {attempt}).", extra={&#x27;trace_id&#x27;: trace_id})&#xA;&#xA;                # Convert to WAV format&#xA;                wav_io = await convert_to_wav(chunk_bytes, idx)&#xA;                if not wav_io:&#xA;                    logger.error(f"Failed to convert chunk {idx &#x2B; 1} to WAV format.")&#xA;                    return ""&#xA;&#xA;                wav_io.name = "chunk.wav"&#xA;                chunk_transcription = await consultation_processor.transcribe_audio_whisper(wav_io)&#xA;                logger.info(f"Chunk {idx &#x2B; 1} transcribed successfully.", extra={&#x27;trace_id&#x27;: trace_id})&#xA;                return chunk_transcription&#xA;            except Exception as e:&#xA;                logger.error(f"Error transcribing chunk {idx &#x2B; 1} (attempt {attempt}): {str(e)}", exc_info=True,&#xA;                             extra={&#x27;trace_id&#x27;: trace_id})&#xA;                if attempt &lt; max_retries:&#xA;                    await asyncio.sleep(retry_delay)&#xA;                else:&#xA;                    await send_discord_alert(&#xA;                        f"Max retries reached for chunk {idx &#x2B; 1} in consultation {consultation.consultation_id}.\nError: {str(e)}\nTrace ID: {trace_id}"&#xA;                    )&#xA;                    return ""  # Return empty string for failed chunk&#xA;&#xA;    await notification_manager.send_personal_message(&#xA;        f"Consultation {consultation.consultation_id} is being transcribed.", vet_email&#xA;    )&#xA;&#xA;    try:&#xA;        idx = 0&#xA;        full_transcription = []&#xA;        async for chunk in stream_blob_in_chunks(blob, chunk_size_bytes):&#xA;            transcription = await transcribe_chunk(idx, chunk)&#xA;            if transcription:&#xA;                full_transcription.append(transcription)&#xA;            idx &#x2B;= 1&#xA;&#xA;        combined_transcription = " ".join(full_transcription)&#xA;        consultation.full_transcript = (consultation.full_transcript or "") &#x2B; " " &#x2B; combined_transcription&#xA;        consultation_service.save_consultation(clinic_id, vet_email, consultation)&#xA;        logger.info(f"Transcription saved for consultation {consultation.consultation_id}.",&#xA;                    extra={&#x27;trace_id&#x27;: trace_id})&#xA;&#xA;    except Exception as e:&#xA;        logger.error(f"Error during transcription process: {str(e)}", exc_info=True, extra={&#x27;trace_id&#x27;: trace_id})&#xA;        await send_discord_alert(&#xA;            f"Error during transcription process for consultation {consultation.consultation_id}.\nError: {str(e)}\nTrace ID: {trace_id}"&#xA;        )&#xA;        return&#xA;&#xA;    await notification_manager.send_personal_message(&#xA;        f"Consultation {consultation.consultation_id} has been transcribed.", vet_email&#xA;    )&#xA;&#xA;    try:&#xA;        template_service = TemplateService()&#xA;        medical_record_template = template_service.get_template_by_name(&#xA;            consultation.medical_record_template_id).sections&#xA;&#xA;        sections = await consultation_processor.extract_structured_sections(&#xA;            transcription=consultation.full_transcript,&#xA;            notes=notes,&#xA;            language=language,&#xA;            template=medical_record_template,&#xA;        )&#xA;        consultation.sections = sections&#xA;        consultation_service.save_consultation(clinic_id, vet_email, consultation)&#xA;        logger.info(f"Sections processed for consultation {consultation.consultation_id}.",&#xA;                    extra={&#x27;trace_id&#x27;: trace_id})&#xA;    except Exception as e:&#xA;        logger.error(f"Error processing sections for consultation {consultation.consultation_id}: {str(e)}",&#xA;                     exc_info=True, extra={&#x27;trace_id&#x27;: trace_id})&#xA;        await send_discord_alert(&#xA;            f"Error processing sections for consultation {consultation.consultation_id}.\nError: {str(e)}\nTrace ID: {trace_id}"&#xA;        )&#xA;        raise e&#xA;&#xA;    await notification_manager.send_personal_message(&#xA;        f"Consultation {consultation.consultation_id} is fully processed.", vet_email&#xA;    )&#xA;    logger.info(f"Successfully processed consultation {consultation.consultation_id}.",&#xA;                extra={&#x27;trace_id&#x27;: trace_id})&#xA;&#xA;

    &#xA;

  • Can I make calls to APIs such as youtube-dl and ffmpeg from a chrome-app ?

    8 janvier 2015, par ErickR

    First of all, I haven’t started the implementation of the system I’m about to describe, as I didn’t want to commit on implementing something I did not know if was possible.

    So, what I’m trying to achieve is to build a chrome-app to download the audio from certain websites (e.g. youtube and soundcloud) using youtube-dl, post process it using ffmpeg and then upload it to a cloud service via some api. The reason I want to do it via a chrome-app is because I could do all the work on the client side (no need for servers) and I’d have the ability to insert javascript into the pages using content scripts, which would make the app pretty simple to use (I could create buttons such as ’download song’ and stuff like that).

    Although I have already read the documentation explaining the NaCl Technical Overview and some of the Application Structure, I still am not sure as to whether I would be able to make these calls via some C/C++ module or if I would get denied due to security reasons.

    To summarize : considering that the user has the needed dependencies in his system (youtube-dl, python, ffmpeg and etc.), is it possible to make calls to third party APIs such as the ones described before via a chrome-app using NaCl ?

    Thank you all in advance,