• הרשמה
    • התחברות
    • חיפוש
    • דף הבית
    • אינדקס קישורים
    • פוסטים אחרונים
    • קבלת התראות מהדפדפן
    • משתמשים
    • חיפוש בהגדרות המתקדמות
    • חיפוש גוגל בפורום
    • ניהול המערכת
    • ניהול המערכת - שרת private
    1. דף הבית
    2. הלוי הלוי
    3. פוסטים
    ה
    • פרופיל
    • עוקב אחרי 0
    • עוקבים 1
    • נושאים 14
    • פוסטים 54
    • הגבוה ביותר 15
    • שנוי במחלוקת 0
    • קבוצות 0

    הודעות שפורסמו על ידי הלוי הלוי

    • RE: השמעה יומית לפי תאריך עברי, זיהוי אדר ב'

      @yankl
      הנושא ישן,
      הוא גם לא רלוונטי לא לשנה הנוכחית ולא לשנה הבאה שהן שנים פשוטות,
      בכל אופן עברתי עכשיו קצת ומצאתי - אולי יועיל בהמשך אם לא יפתרו את זה בדרך המלך.

      יש פתרון פשוט יחסית, רק להוסיף כמה שורות עבור הקבצים הספציפיים של תחילת אד"א ותחילת ניסן.

      מה שצריך זה רק להגדיר מעבר לשלוחה ייעודית בהקשה על 8 בקובץ המדובר,
      וכן מעבר בסיום הקובץ המסויים לשלוחה הייעודית,
      בשלוחה ההיא להגדיר השמעת קבצים מהתיקייה הנוכחית ולהתחיל מהקובץ הרצוי.

      נניח שאתה נמצא בשלוחה 7 בתפריט הראשי,
      כך צריכה להיראות השלוחה שלך:

      type=playfile
      title=הלימוד היומי
      ;הפעלה לפי תאריך עברי
      folder_play=heb_date
      
      ;שנת תשפ"ז תהיה מעוברת
      ;נצטרך להצמיד את ל' שבט לא' אד"א ואת כ"ט אד"ב לא' ניסן
      
      ;מעבר לל' שבט בהקשת 8 בשיעור א' אד"א
      playfile_57871301_control_play_8=go_to_folder
      playfile_57871301_control_play_8_goto=/meuberet/7_57870530
      ;מעבר לא' אד"א בהקשת 2 בשיעור ל' שבט
      playfile_57870530_control_play_8=go_to_folder
      playfile_57870530_control_play_8_goto=/meuberet/7_57871301
      ;מעבר לל' שבט בסיום שיעור א' אד"א ללא הקשה
      after_play_57871301_go_to_folder=/meuberet/7_57870530
      ;מעבר לכ"ט אד"ב בהקשת 8 בשיעור א' ניסן
      playfile_57870701_control_play_8=go_to_folder
      playfile_57870701_control_play_8_goto=/meuberet/7_57871429
      ;מעבר לא' ניסן בהקשת 2 בשיעור כ"ט אד"ב
      playfile_57871429_control_play_8=go_to_folder
      playfile_57871429_control_play_8_goto=/meuberet/7_57870701
      ;מעבר לכ"ט אד"ב בסיום שיעור א' ניסן ללא הקשה
      after_play_57870701_go_to_folder=/meuberet/7_57871429
      

      ניצור שלוחה חדשה בשם meuberet (מעוברת) - או כל שם אחר שימצא חן בעיניך..
      בתוכה ניצור שלוחה עבור כל הפנייה,
      אני קראתי לשלוחות בשם "שלוחה_קובץ לניתוב פנימי" למען הסדר הטוב, תעשה ככך העולה בדמיונך..

      כך ייראו השלוחות בתיקייה "meuberet":

      ניתוב ל-ל' בשבט התשפ"ז

      type=playfile
      title=ל שבט תשפז
      ;השלוחה ממנה יושמעו הקבצים
      folder_to_play=/7
      ;הקובץ אותו יש להשמיע ראשון
      start_play=57870530
      

      ניתוב ל-א' באדר א' התשפ"ז

      type=playfile
      title=א אדר א תשפז
      folder_to_play=/7
      start_play=57871301
      

      ניתוב ל-כ"ט באדר ב' התשפ"ז

      type=playfile
      title=כט אדר ב תשפז
      folder_to_play=/7
      start_play=57871429
      

      ניתוב ל-א' בניסן התשפ"ז

      type=playfile
      title=א ניסן תשפז
      folder_to_play=/7
      start_play=57870701
      

      בהצלחה!!!

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ה
      הלוי הלוי
    • RE: שליחת API רק בניתוק

      @דוד_מלך_ישראל
      אני משתמש בגוגל סקריפט...
      כך שממילא אני לא יכול להחזיר תגובה אלא משתיק את "אין מענה.." והתגובה תמיד מופיעה בתת שלוחה.
      (מוגדר api_end_goto=1 וכל פעם אני שולח טקסט אחר לפי העניין ל-M0000 של התת שלוחה 1)

      עריכה: עיינתי יותר במה ששלחת, אני רואה שאם לא מתקבלת תגובה, בעצם לא קורה כלום, אני צודק?
      בכל אופן פחות מעניין אותי התגובה שיקבל המשתמש, אני צריך לקבל נתונים רק לאחר שהמשתמש סיים את השיחה (את ההקלטה שנשמרת בניתוק, אין לי דרך לדעת איזה אורך היא תהיה, גם לעשות שלוחת API לאחר ההקלטה אין לי דרך כי המשתמש מנתק ולא ממשיך לטייל במערכת.)

      מה שאני צריך לכאו' לעשות זה פשוט לשלוח פונקציה שתתבצע רק אם מופיע פרמטר hangup.

      function doGet(e) {
      	if (e.parameter.checkRecordHangup && e.parameter.hangup == "yes") {
      		// יש לבצע את הפעולות הנדרשות
      	}
      }
      
      פורסם בפורום מפתחים API
      ה
      הלוי הלוי
    • RE: שליחת API רק בניתוק

      @ivrפון @אביי-ורבא @דוד_מלך_ישראל
      לכאורה מצאתי פתרון הכי פשוט,
      להשאיר הכל כרגיל, והתגובה תבדוק אם hangup=yes, רק אז תעשה את הפעולות שאני צריך בניתוק.
      תודה רבה!!!

      פורסם בפורום מפתחים API
      ה
      הלוי הלוי
    • RE: שליחת API רק בניתוק

      מעניין לעניין בעניין אחר...
      יש לי הרבה שלוחות API במערכת, כולם פונות לאותה כתובת (רק הפונקציות שונות ואכמ"ל)
      אשר על כן, כתבתי כבר ב-ivr.ini את הקישור (api_link=https://..abcd).
      כעת אני לא רוצה לשלוח API ולכן אני רוצה להשאיר ריק את הכתובת.
      מה יגבר?
      הכתובת שרשומה ב-IVR או הכתובת שלא רשומה ב-EXT של השלוחה הנוכחית?
      או שאולי כדאי פשוט לא להשאיר ריק (api_link=) אלא לכתוב שגיאה (api_link=null)?

      תודה מראש!!

      ( @ivrפון @אביי-ורבא )

      פורסם בפורום מפתחים API
      ה
      הלוי הלוי
    • שליחת API רק בניתוק

      אני רוצה להגדיר שלוחה שכל מי שיכנס אליה, בסיום השיחה יישלח API מהמערכת.
      האם יש דבר כזה מובנה במודל API?
      או שאוכל רק 'להתחכם' ולהשאיר ריק ב-api_link ורק את api_hangup_link להגדיר לכתובת הנכונה (וכמובן להחליף לקובץ שקט את M1609 לא מוגדר לינק)
      ????

      תודה מראש!

      פורסם בפורום מפתחים API
      ה
      הלוי הלוי
    • RE: מיקום נוסף לשמירת הקלטות ראוטינג

      @יוסף-ח אם כבר הצעת לבדוק את השיטה הפשוטה והישנה...
      לא עבד גם שכפול והעתקת לינק

      hard_link=yes
      copy_record_link=/1
      
      פורסם בעזרה הדדית למשתמשים מתקדמים
      ה
      הלוי הלוי
    • RE: מיקום נוסף לשמירת הקלטות ראוטינג

      @יוסף-ח מידיעה זה אמור לעבוד או מניחוש?
      כי לי זה לא עובד,
      אני מאמין ג"כ שאם זה היה כ"כ פשוט, זה היה צריך להיות כתוב במודל ראוטינג.
      תודה!!

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ה
      הלוי הלוי
    • RE: מישהו מבין בהקשות DTMF?

      אני רואה שלא מגיבים, כנראה שכתבתי הסבר מידי מסובך...
      הקשות send_dtmf פועלות לי תמיד כדבעי, אני רק צריך תזמון אחר וכדו' לפי הצרכים שלי,
      איך אוכל ליצור קובץ שמע שיעשה את העבודה כמו send_dtmf? מה לא טוב בקוד דלעיל? עוצמה? טון?
      @יעקב פה
      @eliyahu פה
      תודה רבה מראש!!

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ה
      הלוי הלוי
    • מישהו מבין בהקשות DTMF?

      יש לי מערכת שאני גורם לה להתקשר למערכת אחרת (לא בימות ככה"נ)
      ושם להקיש מספר הקשות.
      אני צריך להמתין מספר שניות (להודעת הכותרת של המערכת ההיא)
      אח"כ להקיש כמה ספרות, להמתין שוב ולהקיש עוד כמה ספרות.
      ניסיתי להשתמש ב-send_dtmf
      זה עובד יחסית כמו שצריך, הבעיה היא שנראה שההגדרה הזו לא בדיוק מפותחת...
      ניתן להגדיר שם כמה לחכות בין הקשה להקשה (נראה שזה לא פועל בדיוק כפי ההגדרה, אבל עם זה איכשהו הסתדרתי..)
      מה שעשיתי זה שבכניסה למערכת מוגדרת GO_TO_FOLDER ויש שם קובץ M0000 עם שקט למשך כמה שניות שצריך לפני ההקשה הראשונה.
      עד כאן עובד.
      ניסיתי גם לפני ההמתנה הבאה לעשות שוב את אותו תהליך אבל אם יש הגדרה של send_dtmf הוא מתחיל את השלוחה הבאה עוד לפני שהוא גומר את ההקשות(!) וממילא אני לא יכול להגדיר כמה זמן לעשות את ההמתנה השנייה.

      ניסיתי גם להעלות למערכת קבצים של DTMF שמצאתי (בויקיפדיה יש ובעוד כמה אתרים), היה לי איזשהו קו שעליו זה עבד (במערכות של ימות זה עובד לכאו'), אבל במערכת המדוברת זה לא עובד.
      עשיתי ג"כ קוד בגוגל סקריפט שמעלה למערכת קובץ עם הקשות והמתנה בין ההקשות, הוא גם לא מקיש במערכת ההיא,
      איך אוכל לעשות שזה יעבוד????
      מצורף הקוד:

      // שימוש לדוגמה
      function createExampleDTMFWAV() {
        const digits = '1231234'; // ההקשות לביצוע
        const pauses = [5000, 500, 500, 500, 2000, 500, 500, 500]; // אלפיות שניה להמתנה בין כל הקשה
        const wavBlob = createDTMFWAV(digits, pauses); // יצירת הקובץ
        uploadFile("ivr2:בדיקה/M1012.wav", wavBlob); // העלאה למערכת
      }
      
      /**
       * יוצר קובץ WAV עם צלילי DTMF וזמן שקט.
       * 
       * @param {string} digits - מחרוזת ספרות להמרה לצלילי DTMF.
       * @param {Array<number>} pauses - מערך של משכי הפסקה באלפיות שניות בין הספרות.
       * @return {Blob} - קובץ ה-WAV כ-Blob.
       */
      function createDTMFWAV(digits, pauses) {
        const dtmfFrequencies = {
          '1': [697, 1209],
          '2': [697, 1336],
          '3': [697, 1477],
          '4': [770, 1209],
          '5': [770, 1336],
          '6': [770, 1477],
          '7': [852, 1209],
          '8': [852, 1336],
          '9': [852, 1477],
          '0': [941, 1336],
          '*': [941, 1209],
          '#': [941, 1477]
        };
        
        const sampleRate = 8000;  // 8 kHz
        const toneDuration = 250; // 250 אלפיות השנייה עבור כל צליל DTMF
        const amplitude = 32767;  // Maximum amplitude for 16-bit audio
      
        let samples = [];
        
        for (let i = 0; i < digits.length; i++) {
          // הוסף שקט לפני הטון הראשון ובין צלילים
          let pauseDuration = (i === 0) ? pauses[0] : pauses[i];
          if (pauseDuration > 0) {
            let pauseSamples = Math.floor((pauseDuration / 1000) * sampleRate);
            samples = samples.concat(new Array(pauseSamples).fill(0));
          }
          
          // צור צליל DTMF
          let freqs = dtmfFrequencies[digits[i]];
          if (freqs) {
            let numSamples = Math.floor((toneDuration / 1000) * sampleRate);
            for (let j = 0; j < numSamples; j++) {
              let sampleValue = amplitude * Math.sin(2 * Math.PI * freqs[0] * j / sampleRate)
                              + amplitude * Math.sin(2 * Math.PI * freqs[1] * j / sampleRate);
              samples.push(sampleValue / 2);  // ודא שהאות המשולב נמצא בטווח של 16 סיביות
            }
          }
        }
        
        // המרת דגימות ל-16 סיביות PCM
        let buffer = new ArrayBuffer(samples.length * 2); // 2 בתים לדגימה
        let view = new DataView(buffer);
        for (let i = 0; i < samples.length; i++) {
          view.setInt16(i * 2, samples[i], true);  // Little-endian
        }
        
        // Create WAV file header
        let wavBuffer = new ArrayBuffer(44 + buffer.byteLength);
        let wavView = new DataView(wavBuffer);
        
        // RIFF header
        writeString(wavView, 0, 'RIFF');
        wavView.setUint32(4, 36 + buffer.byteLength, true);
        writeString(wavView, 8, 'WAVE');
        
        // fmt subchunk
        writeString(wavView, 12, 'fmt ');
        wavView.setUint32(16, 16, true);  // Subchunk1Size (16 for PCM)
        wavView.setUint16(20, 1, true);   // AudioFormat (1 for PCM)
        wavView.setUint16(22, 1, true);   // NumChannels (1 for mono)
        wavView.setUint32(24, sampleRate, true); // SampleRate
        wavView.setUint32(28, sampleRate * 2, true); // ByteRate (SampleRate * NumChannels * BitsPerSample/8)
        wavView.setUint16(32, 2, true);   // BlockAlign (NumChannels * BitsPerSample/8)
        wavView.setUint16(34, 16, true);  // BitsPerSample
        
        // data subchunk
        writeString(wavView, 36, 'data');
        wavView.setUint32(40, buffer.byteLength, true);
        new Uint8Array(wavBuffer).set(new Uint8Array(buffer), 44);
        
        // Convert to Blob
        return Utilities.newBlob(new Uint8Array(wavBuffer), 'audio/wav', 'dtmf_tones.wav');
      }
      
      function writeString(view, offset, string) {
        for (let i = 0; i < string.length; i++) {
          view.setUint8(offset + i, string.charCodeAt(i));
        }
      }
      
      /**
       * מעלה קובץ לכתובת ה-URL שצוינה באמצעות בקשת HTTP POST עם נתונים מרובי חלקים/טופס.
       *
       * @param {string} path - הנתיב שבו יש להעלות את הקובץ.
       * @param {Blob} fileBlob - blob הקובץ שיש להעלות.
       */
      function uploadFile(path, fileBlob) {
      
        var YemotUrl = url + 'UploadFile';
      
        var formData = {
          'upload': fileBlob,
          'token': token,
          'path': path
        };
        
        var options = {
          'method': 'post',
          'payload': formData,
          'muteHttpExceptions': true
        };
        
        var response = UrlFetchApp.fetch(YemotUrl, options);
        var responseCode = response.getResponseCode();
        Logger.log(response.getContentText());
        if (responseCode === 200) {
          return JSON.parse(response.getContentText());
        } else {
          return {'שגיאה': 'הבקשה נכשלה עם קוד תגובה ' + responseCode};
        }
      }
      
      פורסם בעזרה הדדית למשתמשים מתקדמים
      ה
      הלוי הלוי
    • מיקום נוסף לשמירת הקלטות ראוטינג

      ברירת מחדל ההקלטות נשמרות בסל המחזור > RoutingRecord
      ברירת מחדל שם הקובץ הוא בסגנון כזה:
      DID-****-Phone-****-Folder-****-routing-RoutingToPhone-****-Date-2024-06-22-23-28-01.wav

      האם ניתן להגדיר שישמרו גם בשלוחת השמעת קבצים עם מספור אוטומטי?
      תודה מראש!

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ה
      הלוי הלוי
    • RE: סגירת שלוחה אם ספירה לאחור

      @abcABC
      כתבתי לך קוד לגוגל סקריפט,
      נשאר לך לבצע את הפעולות הבאות:

      1. לפתוח כרטיסייה חדשה בדפדפן ולהדביק בו את הקישור הזה (יש להחליף את הכוכביות במספר המערכת ובסיסמה):
      https://www.call2all.co.il/ym/api/Login?username=*****&password=*****
      
      1. להעתיק את מה שכתוב אחרי המילה token.
      2. להיכנס לקישור הזה
      3. למחוק את הפונקציה שכתובה שם ולהדביק את הקוד דלהלן.
      4. להחליף את כל הכוכביות לפי מה שאתה צריך.
      5. ללחוץ למעלה על הכפתור "הפעלה".
      function countdown() {
        var token = "*******" // כאן יש להדביק את הטוקן שהתקבל
        var what = "*******" // כאן יש לכתוב את הנתיב המלא של שלוחת השמעת הקבצים
        // הזמן המדוייק בו השלוחה תיסגר
        var year = **** // כאן יש לכתוב שנה לועזית מלאה ב-4 ספרות
        var month = ** // כאן יש לכתוב חודש לועזי
        var date = ** // כאן יש לכתוב יום בחודש הלועזי
        var hour = ** // כאן יש לכתוב שעה
        var minute = ** // כאן יש לכתוב דקה
        var time = ** // כאן יש לכתוב כמה שעות לפני סגירת השלוחה תתחיל הספירה לאחור
      
        // מכאן והלאה לא נוגעים... (אא"כ אתה מבין מה אתה עושה כמובן)
        const t = new Date(year, month - 1, date, hour, minute);
        for (let d, h, m, fileName, text, i = time * 60; i > 0; i--) {
          d = new Date(year, month - 1, date, hour, minute - i);
          h = Math.floor((t - d) / (1000 * 60 * 60));
          m = Math.floor((t - d) / (1000 * 60)) % 60;
          fileName = `${d.getFullYear()%100}${(d.getMonth()+1).toString().padStart(2,'0')}${d.getDate().toString().padStart(2,'0')}${d.getHours().toString().padStart(2,'0')}${d.getMinutes().toString().padStart(2,'0')}`;
          text = `השלוחה תיסגר בעוד ${h > 0 ? `${h} שעות ` : ``}${(h > 0 && m > 0) ? `ו-` : ``}${m > 0 ? `${m} דקות` : ``}`;
          UrlFetchApp.fetch(`https://www.call2all.co.il/ym/api/UploadTextFile?token=${token}&what=ivr2:${what}/${fileName}.tts&contents=${text}`)
        }
      }
      

      בלי אחריות (לא אמור לעשות תקלות...)
      מקווה שהועלתי.

      פורסם בשאלות ועזרה הדדית
      ה
      הלוי הלוי
    • RE: סגירת שלוחה אם ספירה לאחור

      @abcABC
      לכאורה תוכל להשתמש בתזמון השמעת קבצים - מודול playfile

      type=playfile
      folder_play=timing_file
      

      כאשר הקבצים יהיו הקראת טקסט (TTS)
      וכל קובץ ייקרא בשם הדקה והשעה שיתחיל לפעול,
      למשל אם השלוחה תיסגר בשעה 12 בלילה, הקובץ שיושמע בשעה 8:01 בבוקר של 17/6/24 ייקרא:

      2406170801.tts
      

      והתוכן שלו יהיה:

      השלוחה תיסגר בעוד 15 שעות ו-59 דקות
      

      כמו כן תגדיר שיישמע רק קובץ אחד בשלוחה כדי שלא ישמיע את כל הקבצים שעבר זמנם:

      after_play=return_amount
      return_amount=1
      

      ותגדיר גם מעבר בסיום ההשמעות למיודעתנו השלוחה שתיסגר...

      playfile_end_goto=/השלוחה המדוברת
      

      כמובן תחליף את הודעה M1005 סוף הודעות. בקובץ של שניה שקט
      ואל תשכח להגדיר גם בשלוחה הזו של השמעת הקבצים סגירה באותה שעה...

      לא בדקתי את כל הנ"ל, אבל זה אמור לעבוד... (בדקתי רק שעובד TTS)
      יתכן שזה קצת מורכב לבנות את כל הקבצים,
      תוכל להיעזר באקסל, יותר קל יהיה בגוגל שיטס ובגוגל סקריפט.
      תוכל גם ליצור קובץ M0000.tts עם הטקסט "השלוחה תיסגר בעוד" ואז ישאר לך למלא את הקבצים רק בשעה ודקה..

      פורסם בשאלות ועזרה הדדית
      ה
      הלוי הלוי
    • RE: במודל הקלטות - שם קובץ מוגדר מראש וכן תפריט לפני ההקלטה עצמה.

      @דוד_מלך_ישראל
      וואו!
      זה פשוט עובד!!!
      כתבתי כך:

      type=record_system_messages
      record_system_folder=/1/2
      record_system_messages=שלום
      

      נוצר בשלוחה 1/2 קובץ בשם "שלום.wav" עם ההקלטה המבוקשת!
      זה בדיוק מה שחיפשתי!
      תודה!!!

      נ.ב. לטובת המשתמשים שמגיעים לכאן... קישור להגדרות המודל

      פורסם בבקשות לפיתוח
      ה
      הלוי הלוי
    • RE: במודל הקלטות - שם קובץ מוגדר מראש וכן תפריט לפני ההקלטה עצמה.

      @צבי-ד-צ כתב בבמודל הקלטות - שם קובץ מוגדר מראש וכן תפריט לפני ההקלטה עצמה.:

      @הלוי-הלוי אתה מעוניין שיהי' שמות לקבצים? כי אם כן זה גם בעיה בהשמעת קבצים שלא יוכל להשמיע את הקובץ (כי הוא לא ממוספר)

      לא, כמו שכתבתי, הקבצים לא מיועדים להשמעה במודל השמעת קבצים אלא שיהיו באיזושהי תיקייה במערכת, אח"כ אשתמש בהם לבניית משפטים,
      נניח שכל הקבצים נמצאים בתיקייה בשם "קבצים", וארצה לבנות בשלוחה הראשית קובץ M1000 לתפריט "להקלטות הקישו 1 לשמיעת הודעות 2"
      אשתמש בקוד כזה:

      /**
       * פונקציה ראשית שמורידה קבצים, מחברת אותם לקובץ אחד ואז מעלה אותו.
       */
      function main() {
        const downloadPath = "ivr2:קבצים/";
        const files = ["ל.wav", "הקלטות.wav", "הקישו.wav", "1.wav", "ל.wav", "שמיעת הודעות.wav", "2.wav"];
        const uploadPath = "ivr2:M1000.wav";
      
        // הורדת הקבצים
        const fileBlob = downloadFile(downloadPath, files);
        
        // העלאת הקובץ המחובר
        uploadFile(uploadPath, fileBlob);
      }
      
      /**
       * מוריד קובץ מה-URL שצוין ומחזיר אותו כ-blob.
       *
       * @param {string} path - הנתיב של הקובץ להורדה.
       * @param {string[]} files - רשימת הקבצים להורדה.
       * @return {Blob} הקובץ שהורד כ-blob.
       */
      function downloadFile(path, files) {
        
        var blobs = files.map(function(file) {
          return UrlFetchApp.fetch(`${url}DownloadFile?token=${token}&path=${path}${file}`).getBlob();
        });
      
        var headerSize = 44; // גודל הכותרת של קובץ WAV בבתים
      
        // קרא את הנתונים של הקבצים
        var combinedBytes = [], bytes;
        blobs.forEach(function(blob) {
          bytes = blob.getBytes();
            // שמור את הנתונים ללא הכותרת
            combinedBytes = combinedBytes.concat(Array.from(bytes.slice(headerSize)));
        });
      
        var dataSize = combinedBytes.length, dataSize36 = dataSize + 36;
        var wavTitle = [
          82, 73, 70, 70,  // 'RIFF' ב-ASCII
          dataSize36 & 0xFF, (dataSize36 >> 8) & 0xFF, (dataSize36 >> 16) & 0xFF, (dataSize36 >> 24) & 0xFF,  // גודל הקובץ - 8 בתים
          87, 65, 86, 69,  // 'WAVE' ב-ASCII
          102, 109, 116, 32,  // נתח 'fmt'
          16, 0, 0, 0,  // תת נתח 1 גודל (16 עבור PCM)
          1, 0,  // פורמט שמע (1 עבור PCM)
          1, 0,  // מספר ערוצים (1 עבור מונו, 2 עבור סטריאו)
          64, 31, 0, 0,  // קצב דגימה (8000 הרץ בפורמט ליטל-אנדיאן)
          128, 62, 0, 0,  // קצב בתים (קצב דגימה * מספר ערוצים * סיביות לדגימה / 8)
          2, 0,  // יישור בלוק (מספר ערוצים * ביטים לדגימה / 8)
          16, 0,  // סיביות לדגימה (16 סיביות)
          100, 97, 116, 97,  // נתח 'data'
          dataSize & 0xFF, (dataSize >> 8) & 0xFF, (dataSize >> 16) & 0xFF, (dataSize >> 24) & 0xFF  // גודל נתונים
        ];
        var wav = wavTitle.concat(combinedBytes);
        var combinedBlob = Utilities.newBlob(wav, 'audio/wav', 'combined.wav');
        
        return combinedBlob;
      }
      
      /**
       * מעלה קובץ לכתובת ה-URL שצוינה באמצעות בקשת HTTP POST עם נתונים מרובי חלקים/טופס.
       *
       * @param {string} path - הנתיב שבו יש להעלות את הקובץ.
       * @param {Blob} fileBlob - blob הקובץ שיש להעלות.
       */
      function uploadFile(path, fileBlob) {
      
        var yemotUrl = url + 'UploadFile';
      
        var formData = {
          'upload': fileBlob,
          'token': token,
          'path': path
        };
        
        var options = {
          'method': 'post',
          'payload': formData,
          'muteHttpExceptions': true
        };
        
        var response = UrlFetchApp.fetch(yemotUrl, options);
        var responseCode = response.getResponseCode();
        Logger.log(response.getContentText());
        if (responseCode === 200) {
          return JSON.parse(response.getContentText());
        } else {
          return {'שגיאה': 'הבקשה נכשלה עם קוד תגובה ' + responseCode};
        }
      }
      

      כעת יותר מובן או יותר מסובך??....

      פורסם בבקשות לפיתוח
      ה
      הלוי הלוי
    • במודל הקלטות - שם קובץ מוגדר מראש וכן תפריט לפני ההקלטה עצמה.

      יש לי רשימת הקלטות שונות (כותרות, שמות, תאריכים וכדומה) שמישהו אחר צריך להקליט.
      המקליט נכנס לשלוחה, שומע מה להקליט (החלפתי את קובץ M0102 במילה שצריך להקליט),
      מקליט ועובר להקלטה הבאה (record_end_goto). יצרתי שלוחות רבות, כל אחת עם הודעה מותאמת והגדרת מעבר להקלטה הבאה אחרי ההקלטה.

      אני צריך שני דברים נוספים:

      1. הגדרת שם הקובץ לכל הקלטה: למשל, שהקובץ של "בוקר טוב" ייקרא "בוקר_טוב.wav".
        הגדרת set_record_name=yes לא מתאימה כי השם צריך להיות המילה המוקלטת.
      2. אפשרות לדלג על הקלטה מסוימת: תפריט אחרי שמיעת המילה להקלטה שיאפשר לבחור אם להקליט או לדלג להקלטה הבאה.
        כיום (עד כמה שידוע לי) אין אפשרות כזו במודל ההקלטות.

      אני בונה קו משפחתי ומעוניין להחליף את כל הודעות המערכת בקול של אחי הקטן...
      בניתי קוד שמוריד קבצים מסויימים לפי הצורך, מחבר אותם לקובץ יחיד ומעלה אותו למערכת,
      לכן אני צריך ששמות קבצים כמו המילים המוקלטות ושאפשר יהיה לדלג על הקלטות שכבר הוקלטו.
      אפשר לעשות זאת באמצעות API שאחרי כל הקלטה ישנה את שם הקובץ ויגדיר שבפעם הבאה ידלג על השלוחה של ההקלטה הזו,
      אבל זה קצת מסובך..
      וגם שנתקלתי בצורך לקבוע את שם הקובץ מראש כבר כמה פעמים.
      ואני מאמין שזה יועיל לעוד אנשים.

      הצעתי להוסיף הגדרה לשם קובץ מוגדר מראש:

      set_record_name=שם הקובץ הרצוי
      

      וכן הגדרה לאחר הכניסה לשלוחת הקלטות - בחירה האם להליט או להמשיך להיכן שמוגדר ב-record_end_goto (כמו שיש בהקלטת כותרת)

          record=tfr
      

      תודה מראש!!!

      פורסם בבקשות לפיתוח
      ה
      הלוי הלוי
    • RE: חדש! שמירת קובץ הקלטת שידור חי בתאריך של היום | confbridge

      @חוויה-טלפונית כתב בחדש! שמירת קובץ הקלטת שידור חי בתאריך של היום | confbridge:

      @אלחנן1
      פיתוח מדהים
      אם כבר אז אולי אפשר אולי לעשות גם תפריט הקשה של שם הקובץ

      חדש במודול הקלטות - בחירת שם לקובץ
      זה לא מה שאתה מחפש?
      תוכל ליצור שלוחה של הקלטות ולהעתיק לשלוחת שידור חי.

      פורסם בחדש במערכת
      ה
      הלוי הלוי
    • המתנה ארוכה בחסימת האזנה לקבצים שהמשתמש האזין להם בעבר

      אני משתמש במערכת שלי בשלוחת השמעת קבצים, באפשרות של חסימת האזנה לקובץ שכבר האזין.
      הבעיה היא שהבדיקה על כל קובץ אם שמעו אותו כבר לוקחת הרבה זמן,
      כאשר יש בשלוחה 5 קבצים זה עוד נסבל,
      אבל אם יש לי בשלוחה 20 קבצים או אפילו 100 וזה עולה מפעם לפעם..
      אני שומע את ההודעה החדשה, ואז ממתין המון זמן עד שהוא חוזר לתפריט,
      אני לא רוצה לעבור לתפריט באופן ידני כי עד שלא אשמע את ההודעה במלואה היא לא תירשם בלוג,
      ואני לא יכול לדעת אם זה השקט של בדיקת כל הקבצים או שמישהו הקליט הודעה ושכח לנתק...

      האם יש פתרון לבעיה הזו?
      האם מישהו שם לב לעניין הזה?

      פורסם בבאגים במערכת
      ה
      הלוי הלוי
    • RE: מספור הקלטה ושם קובץ מוגדר מראש

      @שמחה-זו-הסיסמא כתב במספור הקלטה ושם קובץ מוגדר מראש:

      @הלוי-הלוי
      תראה גם כאן
      https://f2.freeivr.co.il/post/79598

      זה באמת נראה קרוב למה שאני מחפש ונראה שזה גם מה ש - @yankl חיפש.
      שאלה 1. האם ניתן להגדיר את playdir_time_type=admin גם עבור הקלטה רגילה שאיננה שידור חי?
      שאלה 2. האם ניתן להגדרה גם על תאריך עברי?
      שאלה 3. האם אוכל איכשהו לדלג על אפשרויות ההקשה ומייד ייחשב שהקישו 00 לתאריך של היום?

      @שמחה-זו-הסיסמא תודה רבה רבה!!
      תזכה למצוות רבות!!!
      אין לך מושג כמה זה יחסוך לי..
      במערכת משתמשים לא רק רב אחד ולא רק בשלוחה אחת (בלשון המעטה...).
      כל פעם במוצאי שבת אני צריך לשנות את השם של הקובץ הריק בשביל שההקלטה של יום ראשון תהיה בתאריך הנכון...
      באדר א' ואדר ב' זה היה עוד יותר מסובך, כי שבט הוא 05, אד"א הוא 13 ואד"ב הוא 14,
      הבעיה הכי גדולה תהיה לי (אם לא ייפתר עד אז) בניסן, כי אם לא אשנה את כל שמות הקבצים של האדרים,
      הכל יהיה רחוק מאד מניסן - 07.

      פחות או יותר זה עובד כך:
      אחרי ל שבט תשפד - 57840530,
      אם לא הייתי כותב קובץ ריק בשם - 57841300,
      הקובץ הבא היה - 57840531 במקום - 57841301,
      כך אני עושה בכל ראש חודש (כל עוד בחודש יש 29/30 יום ולא 100...)
      לקראת ניסן, לא יעזור לי לעשות קובץ בשם - 57840700,
      כי כל אדר א' ואדר ב' הם במספר שיותר גבוה מזה.

      מקווה שהובנתי.. לא מצאתי דרך יותר פשוטה ומובנת...

      פורסם בבקשות לפיתוח
      ה
      הלוי הלוי
    • RE: מספור הקלטה ושם קובץ מוגדר מראש

      @שמחה-זו-הסיסמא
      כוונתך לבחירת שם לקובץ?
      זה לא יעזור לי כי אמרתי לרב על אילו מקשים ללחוץ כדי לבצע הקלטה בתחילת השיעור,
      אין לי אפשרות להטריח אותו בסיום להתחיל לחשב את השנה, חודש, יום ולהקיש...

      פורסם בבקשות לפיתוח
      ה
      הלוי הלוי
    • RE: מספור הקלטה ושם קובץ מוגדר מראש

      @yankl
      הנושא באמת נצרך וחשוב מאד, חיפשתי הרבה בפורום פיתרון לבעיה הזו.
      אם הבנתי נכון את שאלתך, תוכל להשתמש בהגדרת זמנים להשמעת הקובץ.
      זה לא מה שאתה מחפש?

      פורסם בבקשות לפיתוח
      ה
      הלוי הלוי