Create an Audio Message and Share it on Twitter

Step 1: Create your Twitter Developer account:

1️⃣ Create a common twitter account, click the link and follow the steps to create your twitter account: https://help.twitter.com/en/using-twitter/create-twitter-account.
2️⃣ Then, sign up at Twitter developer: https://developer.twitter.com/en

👍

Already have a Twitter developer account?

Move on to step 2!

Step 2: Create App

1️⃣ Go to https://developer.twitter.com/en/portal/projects-and-apps and click Create App.
2️⃣ Choose a name, and save your API Key and API secret.
3️⃣ Edit the App permissions to "Read and Write"
4️⃣ Click on "Keys and tokens" and generate "Access Token and Secret". Save the Access Token and the Access Token Secret

Step 3: Start Coding!

1️⃣ Obtain and import your API key
2️⃣ Create your text to speech file!

👍

Customise your script text and choose your favourite speaker and background track!

import aflr

aflr.api_key = "YOUR_API_KEY"

def aflr_create(scriptName, message):
    script = aflr.Script().create(scriptText= message, scriptName=scriptName, moduleName="hello_world", projectName="hello_world")
    print(script)
    response = aflr.Speech().create(scriptId=script.get("scriptId"), voice="Joanna")
    print(response)
    response = aflr.Mastering().create(scriptId=script.get("scriptId"),soundTemplate="heatwave")
    print(response)
    file = aflr.Mastering().download(scriptId=script.get("scriptId"), destination=".")
    file = aflr.Mastering().retrieve(scriptId=script.get("scriptId"))
    return file["url"]
aflr_create("hello_world", "Enjoy the API! Write your message here!")
const Aflr = require("aflr").default;

const api_key = "YOUR_API_KEY";

let fileName;
let url_mp3;

async function aflr_create(fileName) {
  try {
    Aflr.configure({ apiKey: api_key });
    let script = await Aflr.Script.create({
      scriptText: "Enjoy the API. Write your text here!",
      projectName: "hello_world",
      moduleName: "hello_world",
      scriptName: fileName,
    });
    script = await Aflr.Script.retrieve(script["scriptId"]);

    let scripts = await Aflr.Script.list();
    console.log(scripts);

    let voices = await Aflr.Voice.list();
    console.log(voices);

    let speech = await Aflr.Speech.create({ scriptId: script["scriptId"] });
    console.log(speech);

    let speechResult = await Aflr.Speech.retrieve(script["scriptId"]);
    console.log(speechResult);

    let bg_tracks = await Aflr.Sound.list();
    console.log(bg_tracks);

    let mastering = await Aflr.Mastering.create({
      scriptId: script["scriptId"],
      backgroundTrackId: bg_tracks[4]["id"],
    });
    console.log(mastering);

    let masteringResult = await Aflr.Mastering.retrieve(script["scriptId"], {});
    console.log(masteringResult.url);
    url_mp3 = masteringResult.url;
    return url_mp3;
  } catch (e) {
    console.error(e);
  }
}

// Use the following function to download the mp3 from the url retrieved

function downloadUrl() {
  try {
    https.get(url_mp3, function (res) {
      const fileStream = fs.createWriteStream(fileName.concat(".mp3"));
      res.pipe(fileStream);
      fileStream.on("finish", function () {
        fileStream.close();
        console.log("mp3 audio file downloaded");
      });
    });
  } catch (e) {
    console.log(e);
  }
}

Step 4. Go fancy!

In Twitter it is possible to tweet up to 4 photos, or gif or one video, and it is possible to write up to 280 characters + links.
Let's create a video with the audio file we have just created and the logo of API.audio.
Now let's upload it with the link to download the audio file!

import ffmpeg
import requests
import os

def get_logo():
    response = requests.get("https://i.ibb.co/drq9x1P/aflr-logo.png")
    file = open("logo.png", "wb")
    file.write(response.content)
    file.close()

def rm_logo():
    os.remove("./logo.png")

def combine_audio(filename):
    get_logo()
    path = "{}.mp3".format(filename)
    output_path = "audio.m4a"
    ffmpeg.input(path).output(output_path).run()
    import moviepy.editor as mpe
    audio_clip = mpe.AudioFileClip(output_path)
    image_clip = mpe.ImageClip("logo.png").set_duration(audio_clip.duration)
    image_clip = image_clip.set_audio(audio_clip)
    image_clip.write_videofile("video.mp4", fps=30,  audio_bitrate="300k", audio_codec = "aac")
    os.remove(output_path)
    rm_logo()
const fetch = require("node-fetch");
const fs = require("fs");
const path = require("path");
var ffmpeg = require("fluent-ffmpeg");
var command = ffmpeg();



async function download_logo() {
  try {
    const url = "https://i.ibb.co/drq9x1P/aflr-logo.png";
    const response = await fetch(url);
    const buffer = await response.buffer();
    fs.writeFile("logo.png", buffer, () =>
      console.log("finished logo  downloading")
    );
  } catch (e) {
    console.log("Error at download_logo", e);
  }
}


function make_video() {
  try {
    const input = fileName.concat(".mp3");
    const output = fileName.concat(".mp4");
    ffmpeg(path.join(process.cwd(), input))
      .input("logo.png")
      .fps(30)
      .withVideoBitrate("50")
      .inputOptions(["-r 1", "-loop 1"])
      .audioCodec("aac")
      .outputOptions(["-shortest"])
      .save(path.join(process.cwd(), output));
  } catch (e) {
    console.log("Error at make_video", e);
  }
}

Step 5. Upload the video to Twitter and send a tweet!

Follow the steps below:

# Source code: https://gist.github.com/jcipriano/e506b81a6062307c5189
import sys
import tweepy
from TwitterAPI import TwitterAPI

consumer_key = "-"
consumer_secret = "-"
access_token = "-"
access_token_secret = "-"


twitter = TwitterAPI(consumer_key, consumer_secret, access_token, access_token_secret)

def OAuth_access():
    try:
        auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
        return auth
    except Exception as e:
        print("Error:", e)
        return None

oauth = OAuth_access()
api = tweepy.API(oauth)


def upload_video(url):
    VIDEO_FILENAME = "video.mp4"
    bytes_sent = 0
    total_bytes = os.path.getsize(VIDEO_FILENAME)
    file = open(VIDEO_FILENAME, 'rb')

    def check_status(r):
        if r.status_code < 200 or r.status_code > 299:
            print(r.status_code)
            print(r.text)
            sys.exit(0)

    # initialize media upload and get a media reference ID in the response
    req = twitter.request('media/upload', {'command':'INIT', 'media_type':'video/mp4', 'total_bytes':total_bytes})
    check_status(req)

    media_id = req.json()['media_id']
    segment_id = 0

    # start chucked upload
    while bytes_sent < total_bytes:
        chunk = file.read(4*1024*1024)
    
        # upload chunk of byets (5mb max)
        req = twitter.request('media/upload', {'command':'APPEND', 'media_id':media_id, 'segment_index':segment_id}, {'media':chunk})
        check_status(req)
        segment_id = segment_id + 1
        bytes_sent = file.tell()
        print('[' + str(total_bytes) + ']', str(bytes_sent))

    # finalize the upload
    req = twitter.request('media/upload', {'command':'FINALIZE', 'media_id':media_id})
    check_status(req)

    # post Tweet with media ID from previous request
    req = twitter.request('statuses/update', {'status': "Hey! Click here to download the audio in .mp3 format!: {}".format(url), 'media_ids':media_id})
    check_status(req)
// Source code: https://coderrocketfuel.com/article/publish-text-image-gif-and-video-twitter-posts-with-node-js
const myTweet = {
  content: "This is the text of the tweet",
  twitter_handle: "@YourTwitterAccount",
  access_token: "-",
  access_secret: "-",
};

const TWITTER_API_CONSUMER_KEY = "-";
const TWITTER_API_CONSUMER_SECRET = "-";

function twitter_video_send(myTweet, resolve, reject) {
  try {
    const T = new Twit({
      consumer_key: TWITTER_API_CONSUMER_KEY,
      consumer_secret: TWITTER_API_CONSUMER_SECRET,
      access_token: myTweet.access_token,
      access_token_secret: myTweet.access_secret,
    });

    const PATH = path.join(__dirname, fileName.concat(".mp4"));

    T.postMediaChunked({ file_path: PATH }, function (err, data, response) {
      const mediaIdStr = data.media_id_string;
      const meta_params = { media_id: mediaIdStr };
      console.log("postMediaChunked finished");

      T.post(
        "media/metadata/create",
        meta_params,
        function (err, data, response) {
          if (!err) {
            console.log("media/data/create");
            const params = {
              status: myTweet.content,
              media_ids: [mediaIdStr],
            };
            T.post("statuses/update", params, function (err, tweet, response) {
              const base = "https://twitter.com/";
              const handle = myTweet.twitter_handle;
              const tweet_id = tweet.id_str;
              console.log("statuses/update");
              nodeResolve({
                live_link: `${base}${handle}/status/${tweet_id}`,
              });
            });
          }
        }
      );
    });
  } catch (e) {
    console.log("Error at twitter_video_send", e);
  }
}

End-to-end Example

import aflr
import requests
import sys
import os
import tweepy
from TwitterAPI import TwitterAPI
aflr.api_key ="APIKEY"
consumer_key = "KEY"
consumer_secret = "KEY"
access_token = "KEY"
access_token_secret = "KEY"
twitter = TwitterAPI(consumer_key, consumer_secret, access_token, access_token_secret)
def aflr_create(scriptName, message):
    # Let's create a script and have the text as Hello World!
    script = aflr.Script().create(scriptText= message, scriptName=scriptName, moduleName="recipes", projectName="Working_with_recipes")
    print(script)
    response = aflr.Speech().create(scriptId=script.get("scriptId"), voice="Joanna")
    print(response)
    response = aflr.Mastering().create(scriptId=script.get("scriptId"),soundTemplate="heatwave")
    print(response)
    file = aflr.Mastering().download(scriptId=script.get("scriptId"), destination=".")
    file = aflr.Mastering().retrieve(scriptId=script.get("scriptId"))
    return file["url"]
def get_logo(filename):
    logo = "https://i.ibb.co/Qfvt5F4/Screenshot-2021-04-30-at-17-58-51.png"
    response = requests.get(logo)
    file = open(filename, "wb")
    file.write(response.content)
    file.close()
def rm_logo():
    os.remove("./logo.png")
def combine_audio(audio, image):
    os.system( f"ffmpeg -loop 1 -i {image} -i {audio} -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest final.mp4")
def OAuth_access():
    try:
        auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
        return auth
    except Exception as e:
        print("Error:", e)
        return None
oauth = OAuth_access()
api = tweepy.API(oauth)
def upload_video(url = None):
    VIDEO_FILENAME = "final.mp4"
    bytes_sent = 0
    total_bytes = os.path.getsize(VIDEO_FILENAME)
    file = open(VIDEO_FILENAME, 'rb')
    def check_status(r):
        if r.status_code < 200 or r.status_code > 299:
            print(r.status_code)
            print(r.text)
            sys.exit(0)
    # initialize media upload and get a media reference ID in the response
    req = twitter.request('media/upload', {'command':'INIT', 'media_type':'video/mp4', 'total_bytes':total_bytes})
    check_status(req)
    media_id = req.json()['media_id']
    segment_id = 0
    # start chucked upload
    while bytes_sent < total_bytes:
        chunk = file.read(4*1024*1024)
        # upload chunk of byets (5mb max)
        req = twitter.request('media/upload', {'command':'APPEND', 'media_id':media_id, 'segment_index':segment_id}, {'media':chunk})
        check_status(req)
        segment_id = segment_id + 1
        bytes_sent = file.tell()
        print('[' + str(total_bytes) + ']', str(bytes_sent))
    # finalize the upload
    req = twitter.request('media/upload', {'command':'FINALIZE', 'media_id':media_id})
    check_status(req)
    # post Tweet with media ID from previous request
    req = twitter.request('statuses/update', {'status':f"Hey! Click here to download the audio in .mp3 format!:{url}", 'media_ids':media_id})
    check_status(req)
def create_mp3_and_send_twitter():
    filename = "audioname"
    image = "aflr.png"
    get_logo(image)
    message = "Hey, this is the message you'll hear in your tweet!"
    url = aflr_create(filename, message)
    combine_audio(filename + ".mp3", image)
    upload_video(url)
create_mp3_and_send_twitter()
// npm i aflr https fs node-fetch path twit fluent-ffmpeg @rollup/plugin-node-resolve
const Aflr = require("aflr").default;
const https = require("https");
const fs = require("fs");
const fetch = require("node-fetch");
const path = require("path");
const Twit = require("twit");
const ffmpeg = require("fluent-ffmpeg");
const { nodeResolve } = require("@rollup/plugin-node-resolve");

const TWITTER_API_CONSUMER_KEY = "-";
const TWITTER_API_CONSUMER_SECRET = "-";

const api = "-";
const fileName = "hello_world";

const myTweet = {
  content: `This is the text of the tweet ${url_mp3} `,
  twitter_handle: "@YourTwitterAccount",
  access_token: "-",
  access_secret: "-",
};

let url_mp3;
async function aflr_create() {
  try {
    Aflr.configure({ apiKey: api });
    let script = await Aflr.Script.create({
      scriptText:
        "Enjoy the API",
      projectName: "hello_world",
      moduleName: "hello_world",
      scriptName: fileName,
    });

    script = await Aflr.Script.retrieve(script["scriptId"]);

    let speech = await Aflr.Speech.create({ scriptId: script["scriptId"] });
    console.log("speech");
    let speechResult = await Aflr.Speech.retrieve(script["scriptId"]);
    console.log("speechResult");
    let mastering = await Aflr.Mastering.create({
      scriptId: script["scriptId"],
      backgroundTrackId: "full__citynights.wav",
    });
    console.log("masternig");
    let masteringResult = await Aflr.Mastering.retrieve(script["scriptId"], {});
    console.log("Audio retrieved");
    url_mp3 = masteringResult["url"];
    return Promise.resolve(url_mp3);
  } catch (e) {
    console.error(e);
  }
}

function downloadUrl() {
  try {
    https.get(url_mp3, function (res) {
      const fileStream = fs.createWriteStream(fileName.concat(".mp3"));
      res.pipe(fileStream);
      fileStream.on("finish", function () {
        fileStream.close();
        console.log("mp3 audio file downloaded");
      });
    });
  } catch (e) {
    console.log(e);
  }
}

async function download_logo() {
  try {
    const url = "https://i.ibb.co/drq9x1P/aflr-logo.png";
    const response = await fetch(url);
    const buffer = await response.buffer();
    fs.writeFile("logo.png", buffer, () =>
      console.log("finished logo  downloading")
    );
  } catch (e) {
    console.log("Error at download_logo", e);
  }
}

function rm_logo(image) {
  fs.unlink(image, (err) => {
    if (err) {
      console.error(err);
      return;
    }
  });
}

function make_video() {
  try {
    const input = fileName.concat(".mp3");
    const output = fileName.concat(".mp4");
    ffmpeg(path.join(process.cwd(), input))
      .input("logo.png")
      .fps(30)
      .withVideoBitrate("50")
      .inputOptions(["-r 1", "-loop 1"])
      .audioCodec("aac")
      .outputOptions(["-shortest"])
      .save(path.join(process.cwd(), output));
  } catch (e) {
    console.log("Error at make_video", e);
  }
}

function twitter_video_send(myTweet, resolve, reject) {
  try {
    const T = new Twit({
      consumer_key: TWITTER_API_CONSUMER_KEY,
      consumer_secret: TWITTER_API_CONSUMER_SECRET,
      access_token: myTweet.access_token,
      access_token_secret: myTweet.access_secret,
    });

    const PATH = path.join(__dirname, fileName.concat(".mp4"));

    T.postMediaChunked({ file_path: PATH }, function (err, data, response) {
      const mediaIdStr = data.media_id_string;
      const meta_params = { media_id: mediaIdStr };
      console.log("postMediaChunked finished");

      T.post(
        "media/metadata/create",
        meta_params,
        function (err, data, response) {
          if (!err) {
            console.log("media/data/create");
            const params = {
              status: myTweet.content,
              media_ids: [mediaIdStr],
            };
            T.post("statuses/update", params, function (err, tweet, response) {
              const base = "https://twitter.com/";
              const handle = myTweet.twitter_handle;
              const tweet_id = tweet.id_str;
              console.log("statuses/update");
              nodeResolve({
                live_link: `${base}${handle}/status/${tweet_id}`,
              });
            });
          }
        }
      );
    });
  } catch (e) {
    console.log("Error at twitter_video_send", e);
  }
}

async function downloadAudio_sendTweet() {
  await aflr_create();
  downloadUrl();
  await download_logo();
  make_video();
  twitter_video_send(myTweet);
}

downloadAudio_sendTweet();

Did this page help you?