JsonConvert.DeserializeObject() 上的 Twilio 下载记录到文件抛出错误

Twilio download recording to file throwing error on JsonConvert.DeserializeObject()

我正在尝试将我在 Twilio 上的录音下载到我的服务器本地文件系统上的一个文件中(这样我就可以将它们发送到另一个存储位置),但是按照我发现的代码在JsonConvert.DeserializeObject() 调用。

我找到的代码在这里(称为 "Retrieve the actual recording media"):https://www.twilio.com/docs/video/api/recordings-resource#filter-by-participant-sid

代码如下:

static void Main(string[] args)
{
    // Find your Account SID and Auth Token at twilio.com/console
    const string apiKeySid = "SKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    const string apiKeySecret = "your_api_key_secret";

    const string recordingSid = "RTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    const string uri = $"https://video.twilio.com/v1/Recordings/{recordingSid}/Media";

    var request = (HttpWebRequest)WebRequest.Create(uri);
    request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(apiKeySid + ":" + apiKeySecret)));
    request.AllowAutoRedirect = false;
    string responseBody = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
    var mediaLocation = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseBody)["redirect_to"];

    Console.WriteLine(mediaLocation);
    new WebClient().DownloadFile(mediaLocation, $"{recordingSid}.out");
}

这是我的版本:

        var twilioRecordingUri = $"https://api.twilio.com/2010-04-01/Accounts/{recording.AccountSid}/Recordings/{recording.Sid}.mp3?Download=true";

        var request = (HttpWebRequest)WebRequest.Create(new Uri(twilioRecordingUri));
        request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiKeySid}:{apiKeySecret}")));
        request.ContentType = "audio/mpeg";
        //request.Accept = "audio/mpeg";
        request.AllowAutoRedirect = false;

        var responseBody = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
        var deserialized = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseBody);
        var mediaLocation = deserialized["redirect_to"];

        new WebClient().DownloadFile(mediaLocation, $"{recording.Sid}.out");

但是执行该代码时,它在 JsonConvert.Deserialize() 上失败了,就像我提到的那样;它抛出这个通用的 Json 错误:

Unexpected character encountered while parsing value: �. Path '', line 0, position 0.

将鼠标悬停在我的 "responseBody" 变量上确实表明它是一长串古怪的字符。

我的想法是,我应该将 "Accept" 或 "Content-type" 添加到 "audio/mpeg",因为这是我要检索的文件类型。但是当在请求和响应 headers 中检查 Dev Tools 时,Accept 或 Content-type 都没有得到我刚刚指定的 audio/mpeg 设置。

这段代码有什么问题?

编辑: 对于注意到下载 URL 与 Twilio 示例不同的任何人,我发现此页面已更新 URL:How do I get a call recording url in twilio when programming in PHP?

您尝试进行的调用似乎是下载 .mp3 文件而不是 Dictionary<string, string>,因此在尝试将字符串反序列化为类型时可能会遇到错误它不匹配。结果您可能看到的是一个 Base64 字符串,尤其是根据您的描述。至少没有看到数据样本,我无法确定,但我猜你正在下载原始 .mp3 文件而不是带有位置的文件信息 (redirect_to) .

如果结果是一个纯 Base64 字符串,您应该能够将它转换为一个字节数组,然后将其直接写入一个您想要的任何文件名的文件。那应该让你得到你想要的 mp3 文件。

我发布这个答案只是为了展示 "working" 版本的样子。是@Grungondola 的回答提示了我。感谢他(以及接受的答案)。

private async Task DownloadRecording(RecordingResource recording, string fileName)
{
    if (string.IsNullOrEmpty(fileName))
        throw new ArgumentNullException("fileName is required when downloading a recording.");

    var twilioRecordingUri = $"https://api.twilio.com/2010-04-01/Accounts/{recording.AccountSid}/Recordings/{recording.Sid}.mp3?Download=false";

    var request = (HttpWebRequest)WebRequest.Create(new Uri(twilioRecordingUri));
    request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiKeySid}:{apiKeySecret}")));
    request.ContentType = "audio/mpeg";
    request.AllowAutoRedirect = false;

    var stream = request.GetResponse().GetResponseStream();

    var virtualPath = HttpContext.Server.MapPath(fileName);
    var fileStream = new FileStream(virtualPath, FileMode.Create);

    await stream.CopyToAsync(fileStream);
    fileStream.Close();
}