#Code works with []const u8, but not with []u8

1 messages · Page 1 of 1 (latest)

fickle phoenix
#

Hi, I have the following code:

    var url: []const u8 = undefined;
    var track: ?yt.TrackInfo = null;

    if (res.args.search) |query| {
        const tracks = try yt.search(allocator, query, 20);
        defer allocator.free(tracks);

        const stdout = std.io.getStdOut().writer();
        for (tracks, 1..) |t, i| {
            try stdout.print("[{d}] {s}\n", .{ i, t.title });
        }

        try stdout.print("Select a number (1-{d}): ", .{tracks.len});
        // read input ...

        track = tracks[id - 1];
    }

    if (track == null) {
        if (res.positionals[0]) |pos| {
            url = pos;
        } else {
            const stderr = std.io.getStdErr().writer();
            try stderr.print("You need to specify an url\nUSAGE:\n", .{});
            return clap.help(stderr, clap.Help, &params, .{});
        }
    }

    var yt_stream = Youtube.init(allocator, CHANNELS, SAMPLE_RATE);
    defer yt_stream.deinit();

    if (track) |t| {
        try yt_stream.playFromTrack(t);
    } else {
        try yt_stream.playFromUrl(url);
    }

    var buffer: [BUFFER_SIZE * CHANNELS * @sizeOf(f32)]f32 = undefined;
    while (should_run) {
        const bytes_read = try yt_stream.stdout.read(std.mem.sliceAsBytes(&buffer));
        if (bytes_read == 0) break;
        audio.write(f32, &buffer, bytes_read / (CHANNELS * @sizeOf(f32))) catch {};
    }

This code works fine with yt_stream.playFromUrl(...), but when It uses yt_stream.playFromTrack(...) it doesn't crash but there is no audio, just noice.

#

The implementation is the following:

    pub fn playFromTrack(self: *@This(), track: TrackInfo) !void {
        self.current_track = track;
        try self.play(&track.url);
    }
    pub fn playFromUrl(self: *@This(), url: []const u8) !void {
        self.current_track = try getTrackInfo(self.allocator, url);
        try self.play(url);
    }

    fn play(self: *@This(), url: []const u8) !void {

        var cmd_buffer: [2048]u8 = undefined;
        const cmd_print = try std.fmt.bufPrint(&cmd_buffer, "yt-dlp --quiet --ignore-errors --flat-playlist -o - {s}  2> yt-dlp.out | ffmpeg -i pipe:0 -vn -ac {d} -ar {d} -f f32le pipe:1 2> ffmpeg.out", .{ url, self.channels, self.sample_rate });
        const command = [_][]const u8{ "sh", "-c", cmd_print };

        std.log.debug("{any}", .{cmd_print});

        self.child = std.process.Child.init(&command, self.allocator);
        self.child.stdin_behavior = .Ignore;
        self.child.stderr_behavior = .Ignore;
        self.child.stdout_behavior = .Pipe;

        try self.child.spawn();
        self.stdout = self.child.stdout.?;

        const id = self.current_track.?.url;
        const title = self.current_track.?.title;
        const duration = self.current_track.?.duration;
        std.log.info("Playing: ({s}) {s} - {s}", .{ id, title, duration });
    }
#

using std.log.debug("{any}", .{cmd_print}); to debug, both cmd bytes are exactly the same.

#
pub const TrackInfo = struct {
    url: [64]u8,
    title: [256]u8,
    duration: [16]u8,
};
#

Also, I don't have any error from yt-dlp or ffmpeg

frail prism
fickle phoenix
#

yeah, that's not what I want. Can I use '\0' at the end?

#

or should I define another struct field?

#

even with that, I find strange that both commands are exactly the same

frail prism
#

a few options:

  • add a url_len: usize, etc field and then pass track.url[0..track.url_len]
  • add a '\x00'/NUL after the end of the url and then use std.mem.sliceTo(&track.url, 0) (could also make url a [64:0]u8 but not techincally necessary)
  • probably other options i've not thought of
#

could also make those fields a std.BoundedArray instead, which is an array plus a length

#

then you'd pass track.url.slice()

fickle phoenix
#

awesome, it works

#

thank you!

#

I will check std.BoundedArray

#

why does the code doesn't work even with the buffer is the same in both cases?

#

I started printing the content because at first I thought about the remaining bytes, but both are the same

#

Ah maybe there are invalid characters with no representation

frail prism